chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# isort: skip_file
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Target description and codegen module.
|
||||
|
||||
TVM uses JSON-based target configuration. Targets can be constructed via:
|
||||
|
||||
- A config dictionary: ``Target({"kind": "cuda", "arch": "sm_80"})``
|
||||
- A tag name: ``Target("nvidia/nvidia-a100")``
|
||||
- A tag with overrides: ``Target({"tag": "nvidia/nvidia-a100", "l2_cache_size_bytes": 12345})``
|
||||
- A kind name: ``Target("cuda")``
|
||||
|
||||
Use ``target.attrs["key"]`` to access target attributes such as
|
||||
``"arch"``, ``"max_num_threads"``, ``"mcpu"``, ``"libs"``, etc.
|
||||
|
||||
Use :py:func:`tvm.target.list_tags` to list all available target tags,
|
||||
and :py:func:`tvm.target.register_tag` to register new tags.
|
||||
"""
|
||||
|
||||
from .target import Target, TargetKind
|
||||
from .virtual_device import VirtualDevice
|
||||
from .tag import list_tags, register_tag
|
||||
from . import codegen
|
||||
from . import tag_registry # registers tags on import
|
||||
@@ -0,0 +1,21 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""FFI APIs for tvm.target"""
|
||||
|
||||
import tvm_ffi
|
||||
|
||||
tvm_ffi.init_ffi_api("target", __name__)
|
||||
@@ -0,0 +1,269 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Code generation related functions."""
|
||||
|
||||
from tvm_ffi import Array
|
||||
|
||||
from . import _ffi_api
|
||||
from .target import Target
|
||||
|
||||
|
||||
def build_module(mod, target):
|
||||
"""Build IRModule into Module.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mod : tvm.IRModule
|
||||
The ir module.
|
||||
|
||||
target : str
|
||||
The target module type.
|
||||
|
||||
Returns
|
||||
-------
|
||||
module : runtime.Module
|
||||
The corressponding module.
|
||||
"""
|
||||
target = Target(target) if isinstance(target, str) else target
|
||||
return _ffi_api.Build(mod, target)
|
||||
|
||||
|
||||
def target_has_features(cpu_features, target=None):
|
||||
"""Check CPU features for the target's `-mtriple` and `-mcpu` and `-mattr`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : Target
|
||||
The TVM target.
|
||||
cpu_features : str or Array
|
||||
CPU Feature(s) to check.
|
||||
|
||||
Returns
|
||||
-------
|
||||
has_features : bool
|
||||
True if target has the feature(s).
|
||||
"""
|
||||
assert isinstance(target, Target) or target is None
|
||||
assert isinstance(cpu_features, Array | list | tuple | str)
|
||||
has_feats = True
|
||||
cpu_features = [cpu_features] if isinstance(cpu_features, str) else cpu_features
|
||||
for feat in cpu_features:
|
||||
has_feats &= _ffi_api.target_has_feature(feat, target)
|
||||
return has_feats
|
||||
|
||||
|
||||
def llvm_lookup_intrinsic_id(name):
|
||||
"""Lookup LLVM intrinsic id by name.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name : str
|
||||
The name of the intrinsic.
|
||||
|
||||
Returns
|
||||
-------
|
||||
intrin_id : int
|
||||
The intrinsic id.
|
||||
"""
|
||||
return _ffi_api.llvm_lookup_intrinsic_id(name)
|
||||
|
||||
|
||||
def llvm_get_intrinsic_name(intrin_id: int) -> str:
|
||||
"""Get the name of an intrinsic for a given id.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
intrin_id : int
|
||||
The id of the intrinsic.
|
||||
|
||||
Returns
|
||||
-------
|
||||
name : str
|
||||
The name of the intrinsic.
|
||||
"""
|
||||
return _ffi_api.llvm_get_intrinsic_name(intrin_id)
|
||||
|
||||
|
||||
def llvm_get_system_x86_vendor():
|
||||
"""Get system x86 vendor info.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
Returns
|
||||
-------
|
||||
vendor : str
|
||||
The current system's cpu vendor.
|
||||
"""
|
||||
return _ffi_api.llvm_get_system_x86_vendor()
|
||||
|
||||
|
||||
def llvm_get_system_triple():
|
||||
"""Get system host triple.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
Returns
|
||||
-------
|
||||
triple : str
|
||||
The current system's triple.
|
||||
"""
|
||||
return _ffi_api.llvm_get_system_triple()
|
||||
|
||||
|
||||
def llvm_get_system_cpu():
|
||||
"""Get system host cpu name.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
Returns
|
||||
-------
|
||||
cpu_name : str
|
||||
The current system's cpu name.
|
||||
"""
|
||||
return _ffi_api.llvm_get_system_cpu()
|
||||
|
||||
|
||||
def llvm_get_targets():
|
||||
"""Get LLVM target list.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
Returns
|
||||
-------
|
||||
llvm_targets : list[str]
|
||||
List of available LLVM targets.
|
||||
"""
|
||||
return _ffi_api.llvm_get_targets()
|
||||
|
||||
|
||||
def llvm_get_cpu_archlist(target=None):
|
||||
"""Get CPU architectures for the target's `-mtriple`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : Target
|
||||
The TVM target.
|
||||
|
||||
Returns
|
||||
-------
|
||||
cpu_archlist : list[str]
|
||||
List of available CPU architectures.
|
||||
"""
|
||||
assert isinstance(target, Target) or target is None
|
||||
return _ffi_api.llvm_get_cpu_archlist(target)
|
||||
|
||||
|
||||
def llvm_get_cpu_features(target=None):
|
||||
"""Get CPU features for the target's `-mtriple` and `-mcpu` and considering `-mattr`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : Target
|
||||
The TVM target.
|
||||
|
||||
Returns
|
||||
-------
|
||||
cpu_features : list[str]
|
||||
List of available CPU features.
|
||||
"""
|
||||
assert isinstance(target, Target) or target is None
|
||||
feature_map = _ffi_api.llvm_get_cpu_features(target)
|
||||
return set(feature_map.keys())
|
||||
|
||||
|
||||
def llvm_cpu_has_features(cpu_features, target=None):
|
||||
"""Check CPU features for the target's `-mtriple` and `-mcpu` and considering `-mattr`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : Target
|
||||
The TVM target.
|
||||
cpu_features : str or Array
|
||||
CPU Feature(s) to check.
|
||||
|
||||
Returns
|
||||
-------
|
||||
has_features : bool
|
||||
True if target CPU has the feature(s).
|
||||
"""
|
||||
assert isinstance(target, Target) or target is None
|
||||
assert isinstance(cpu_features, Array | list | tuple | str)
|
||||
has_feats = True
|
||||
cpu_features = [cpu_features] if isinstance(cpu_features, str) else cpu_features
|
||||
for feat in cpu_features:
|
||||
has_feats &= _ffi_api.llvm_cpu_has_feature(feat, target)
|
||||
return has_feats
|
||||
|
||||
|
||||
def llvm_get_vector_width(target=None):
|
||||
"""Get vector width from LLVM target's `-mtriple` and `-mcpu` and considering `-mattr`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : Target
|
||||
The TVM target.
|
||||
|
||||
Returns
|
||||
-------
|
||||
vector_width : int
|
||||
Vector with of target in number of bits, -1 on error.
|
||||
"""
|
||||
assert isinstance(target, Target) or target is None
|
||||
return _ffi_api.llvm_get_vector_width(target)
|
||||
|
||||
|
||||
def llvm_is_valid_cpu(cpu, triple):
|
||||
"""Check if a CPU name is valid for the given LLVM triple.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cpu : str
|
||||
The CPU name to check (e.g. "apple-m1").
|
||||
triple : str
|
||||
The LLVM target triple (e.g. "arm64-apple-macos").
|
||||
|
||||
Returns
|
||||
-------
|
||||
is_valid : bool
|
||||
True if the CPU name is recognized by LLVM for the given triple.
|
||||
"""
|
||||
return _ffi_api.llvm_is_valid_cpu(cpu, triple)
|
||||
|
||||
|
||||
def llvm_version_major(allow_none=False):
|
||||
"""Get the major LLVM version.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
allow_none : bool
|
||||
Whether do we allow none.
|
||||
|
||||
Returns
|
||||
-------
|
||||
major : int
|
||||
The major LLVM version.
|
||||
"""
|
||||
try:
|
||||
return _ffi_api.llvm_version_major()
|
||||
except AttributeError:
|
||||
if allow_none:
|
||||
return None
|
||||
raise RuntimeError("LLVM version is not available, please check if you built TVM with LLVM")
|
||||
@@ -0,0 +1,85 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Detect target."""
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
from tvm_ffi import get_global_func
|
||||
|
||||
from ..runtime import Device, device
|
||||
from . import Target
|
||||
|
||||
|
||||
def _detect_cpu(dev: Device) -> Target: # pylint: disable=unused-argument
|
||||
"""Detect the host CPU architecture."""
|
||||
return Target(
|
||||
{
|
||||
"kind": "llvm",
|
||||
"mtriple": get_global_func(
|
||||
"tvm.codegen.llvm.GetDefaultTargetTriple",
|
||||
allow_missing=False,
|
||||
)(),
|
||||
"mcpu": get_global_func(
|
||||
"tvm.codegen.llvm.GetHostCPUName",
|
||||
allow_missing=False,
|
||||
)(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
SUPPORTED_DEVICE: dict[str, Callable[[Device], Target]] = {
|
||||
"cpu": _detect_cpu,
|
||||
}
|
||||
|
||||
# Backward-compatible alias for the previous private module-level map.
|
||||
SUPPORT_DEVICE = SUPPORTED_DEVICE
|
||||
|
||||
|
||||
def register_device_target_detector(device_type: str, detector: Callable[[Device], Target]) -> None:
|
||||
"""Register target detection for a runtime device type."""
|
||||
SUPPORTED_DEVICE[device_type] = detector
|
||||
|
||||
|
||||
def detect_target_from_device(dev: str | Device) -> Target:
|
||||
"""Detects Target associated with the given device. If the device does not exist,
|
||||
there will be an Error.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dev : Union[str, Device]
|
||||
The device to detect the target for.
|
||||
Supported device types are registered by backend hooks.
|
||||
|
||||
Returns
|
||||
-------
|
||||
target : Target
|
||||
The detected target.
|
||||
"""
|
||||
if isinstance(dev, str):
|
||||
dev = device(dev)
|
||||
device_type = Device._DEVICE_TYPE_TO_NAME[dev.dlpack_device_type()]
|
||||
if device_type not in SUPPORTED_DEVICE:
|
||||
raise ValueError(
|
||||
f"Auto detection for device `{device_type}` is not supported. "
|
||||
f"Currently only supports: {SUPPORTED_DEVICE.keys()}"
|
||||
)
|
||||
if not dev.exist:
|
||||
raise ValueError(
|
||||
f"Cannot detect device `{dev}`. Please make sure the device and its driver "
|
||||
"is installed properly, and TVM is compiled with the driver"
|
||||
)
|
||||
return SUPPORTED_DEVICE[device_type](dev)
|
||||
@@ -0,0 +1,82 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Target dependent intrinsic registration."""
|
||||
|
||||
from tvm.ir import register_intrin_lowering
|
||||
from tvm.tirx import call_pure_extern
|
||||
|
||||
|
||||
def _rule_float_suffix(op):
|
||||
"""Intrinsic rule: Add float suffix if it is float32.
|
||||
|
||||
This is an example intrinsic generation rule.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
op : Expr
|
||||
The call expression of original intrinsic.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ret : Expr
|
||||
The translated intrinsic rule.
|
||||
Return same op if no translation is possible.
|
||||
|
||||
See Also
|
||||
--------
|
||||
register_intrin_lowering : The registration function for intrinsic lowering rule.
|
||||
"""
|
||||
name = op.op.name
|
||||
assert name.startswith("tirx.")
|
||||
prefix = name[4:]
|
||||
|
||||
if op.ty.dtype == "float32":
|
||||
return call_pure_extern(op.ty, f"{prefix}f", *op.args)
|
||||
if op.ty.dtype == "float64":
|
||||
return call_pure_extern(op.ty, prefix, *op.args)
|
||||
return op
|
||||
|
||||
|
||||
def _rule_float_direct(op):
|
||||
"""Intrinsic rule: Directly call pure extern function for floats.
|
||||
|
||||
This is an example intrinsic generation rule.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
op : Expr
|
||||
The call expression of original intrinsic.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ret : Expr
|
||||
The translated intrinsic rule.
|
||||
Return same op if no translation is possible.
|
||||
|
||||
See Also
|
||||
--------
|
||||
register_intrin_lowering : The registration function for intrinsic lowering rule.
|
||||
"""
|
||||
if str(op.ty.dtype).startswith("float"):
|
||||
return call_pure_extern(op.ty, op.op.name[4:], *op.args)
|
||||
return None
|
||||
|
||||
|
||||
# opencl pattern for exp
|
||||
register_intrin_lowering("tirx.exp", target="opencl", f=_rule_float_direct, level=99)
|
||||
# default pattern for exp
|
||||
register_intrin_lowering("tirx.exp", target="default", f=_rule_float_suffix, level=99)
|
||||
@@ -0,0 +1,21 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Target tags -- re-exported from tag_registry.registry."""
|
||||
|
||||
from .tag_registry.registry import list_tags, register_tag
|
||||
|
||||
__all__ = ["list_tags", "register_tag"]
|
||||
@@ -0,0 +1,29 @@
|
||||
# isort: skip_file
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Python-side target tag registry.
|
||||
|
||||
Importing this package registers all Python-defined target tags.
|
||||
"""
|
||||
|
||||
from . import registry
|
||||
from . import arm_cpu
|
||||
from . import riscv_cpu
|
||||
from . import aws_cpu
|
||||
|
||||
# Validate all tags at import time
|
||||
registry.list_tags()
|
||||
@@ -0,0 +1,116 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""ARM CPU target tags."""
|
||||
|
||||
from .registry import register_tag
|
||||
|
||||
# ---------- Raspberry Pi (self-hosted, with host config) ----------
|
||||
register_tag(
|
||||
"raspberry-pi/4b-aarch64",
|
||||
{
|
||||
"kind": "llvm",
|
||||
"mtriple": "aarch64-linux-gnu",
|
||||
"mcpu": "cortex-a72",
|
||||
"mattr": ["+neon"],
|
||||
"num-cores": 4,
|
||||
"host": {
|
||||
"kind": "llvm",
|
||||
"mtriple": "aarch64-linux-gnu",
|
||||
"mcpu": "cortex-a72",
|
||||
"mattr": ["+neon"],
|
||||
"num-cores": 4,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
# ---------- ARM boards ----------
|
||||
def _register_arm_tag(name, config):
|
||||
base = {"kind": "llvm", "keys": ["arm_cpu", "cpu"], "device": "arm_cpu"}
|
||||
base.update(config)
|
||||
register_tag(name, base)
|
||||
|
||||
|
||||
_register_arm_tag(
|
||||
"arm/pixel2",
|
||||
{"model": "snapdragon835", "mtriple": "arm64-linux-android", "mattr": ["+neon"]},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/mate10",
|
||||
{"model": "kirin970", "mtriple": "arm64-linux-android", "mattr": ["+neon"]},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/rasp3b",
|
||||
{"model": "bcm2837", "mtriple": "armv7l-linux-gnueabihf", "mattr": ["+neon"]},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/rasp4b",
|
||||
{
|
||||
"model": "bcm2711",
|
||||
"mtriple": "armv8l-linux-gnueabihf",
|
||||
"mattr": ["+neon"],
|
||||
"mcpu": "cortex-a72",
|
||||
},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/rasp4b64",
|
||||
{
|
||||
"model": "bcm2711",
|
||||
"mtriple": "aarch64-linux-gnu",
|
||||
"mattr": ["+neon"],
|
||||
"mcpu": "cortex-a72",
|
||||
},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/rk3399",
|
||||
{"model": "rk3399", "mtriple": "aarch64-linux-gnu", "mattr": ["+neon"]},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/pynq",
|
||||
{"model": "pynq", "mtriple": "armv7a-linux-eabi", "mattr": ["+neon"]},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/ultra96",
|
||||
{"model": "ultra96", "mtriple": "aarch64-linux-gnu", "mattr": ["+neon"]},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/beagleai",
|
||||
{
|
||||
"model": "beagleai",
|
||||
"mtriple": "armv7a-linux-gnueabihf",
|
||||
"mattr": ["+neon", "+vfp4", "+thumb2"],
|
||||
"mcpu": "cortex-a15",
|
||||
},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/stm32mp1",
|
||||
{
|
||||
"model": "stm32mp1",
|
||||
"mtriple": "armv7a-linux-gnueabihf",
|
||||
"mattr": ["+neon", "+vfp4", "+thumb2"],
|
||||
"mcpu": "cortex-a7",
|
||||
},
|
||||
)
|
||||
_register_arm_tag(
|
||||
"arm/thunderx",
|
||||
{
|
||||
"model": "thunderx",
|
||||
"mtriple": "aarch64-linux-gnu",
|
||||
"mattr": ["+neon", "+crc", "+lse"],
|
||||
"mcpu": "thunderxt88",
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,41 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""AWS CPU instance target tags."""
|
||||
|
||||
from .registry import register_tag
|
||||
|
||||
|
||||
def _register_aws_c5(name, cores, arch):
|
||||
register_tag(
|
||||
name,
|
||||
{
|
||||
"kind": "llvm",
|
||||
"keys": ["x86", "cpu"],
|
||||
"mcpu": arch,
|
||||
"num-cores": cores,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
_register_aws_c5("aws/cpu/c5.large", 1, "skylake-avx512")
|
||||
_register_aws_c5("aws/cpu/c5.xlarge", 2, "skylake-avx512")
|
||||
_register_aws_c5("aws/cpu/c5.2xlarge", 4, "skylake-avx512")
|
||||
_register_aws_c5("aws/cpu/c5.4xlarge", 8, "skylake-avx512")
|
||||
_register_aws_c5("aws/cpu/c5.9xlarge", 18, "skylake-avx512")
|
||||
_register_aws_c5("aws/cpu/c5.12xlarge", 24, "cascadelake")
|
||||
_register_aws_c5("aws/cpu/c5.18xlarge", 36, "skylake-avx512")
|
||||
_register_aws_c5("aws/cpu/c5.24xlarge", 48, "cascadelake")
|
||||
@@ -0,0 +1,69 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Target tag registry functions."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from .. import _ffi_api
|
||||
from ..target import Target
|
||||
|
||||
|
||||
def list_tags() -> dict[str, Target] | None:
|
||||
"""Returns a dict of tags, which maps each tag name to its corresponding target.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tag_dict : Optional[Dict[str, Target]]
|
||||
The dict of tags mapping each tag name to its corresponding target.
|
||||
None if TVM is built in runtime-only mode.
|
||||
"""
|
||||
if hasattr(_ffi_api, "TargetTagListTags"):
|
||||
return _ffi_api.TargetTagListTags()
|
||||
return None
|
||||
|
||||
|
||||
def register_tag(name: str, config: dict[str, Any], override: bool = False) -> Target | None:
|
||||
"""Add a user-defined tag into the target tag registry.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name: str
|
||||
Name of the target, e.g. "nvidia/gtx1080ti"
|
||||
config : Dict[str, Any]
|
||||
The config dict used to create the target
|
||||
override: bool
|
||||
A boolean flag indicating if overriding existing tags are allowed.
|
||||
If False and the tag has been registered already, an exception will be thrown.
|
||||
|
||||
Returns
|
||||
-------
|
||||
target : Optional[Target]
|
||||
The target corresponding to the tag
|
||||
None if TVM is built in runtime-only mode.
|
||||
|
||||
Examples
|
||||
--------
|
||||
.. code-block:: python
|
||||
|
||||
register_tag("nvidia/gtx1080ti", config={
|
||||
"kind": "cuda",
|
||||
"arch": "sm_61",
|
||||
})
|
||||
"""
|
||||
if hasattr(_ffi_api, "TargetTagAddTag"):
|
||||
return _ffi_api.TargetTagAddTag(name, config, override)
|
||||
return None
|
||||
@@ -0,0 +1,84 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""RISC-V CPU target tags (from old riscv_cpu() translation table)."""
|
||||
|
||||
from .registry import register_tag
|
||||
|
||||
|
||||
def _register_riscv_tag(name, config):
|
||||
base = {"kind": "llvm", "keys": ["riscv_cpu", "cpu"], "device": "riscv_cpu"}
|
||||
base.update(config)
|
||||
register_tag(name, base)
|
||||
|
||||
|
||||
_register_riscv_tag(
|
||||
"riscv/sifive-e31",
|
||||
{
|
||||
"model": "sifive-e31",
|
||||
"mtriple": "riscv32-unknown-linux-gnu",
|
||||
"mcpu": "sifive-e31",
|
||||
"mabi": "ilp32",
|
||||
},
|
||||
)
|
||||
_register_riscv_tag(
|
||||
"riscv/sifive-e76",
|
||||
{
|
||||
"model": "sifive-e76",
|
||||
"mtriple": "riscv32-unknown-linux-gnu",
|
||||
"mcpu": "sifive-e76",
|
||||
"mabi": "ilp32",
|
||||
},
|
||||
)
|
||||
_register_riscv_tag(
|
||||
"riscv/sifive-u54",
|
||||
{
|
||||
"model": "sifive-u54",
|
||||
"mtriple": "riscv64-unknown-linux-gnu",
|
||||
"mcpu": "sifive-u54",
|
||||
"mabi": "lp64d",
|
||||
},
|
||||
)
|
||||
_register_riscv_tag(
|
||||
"riscv/sifive-u74",
|
||||
{
|
||||
"model": "sifive-u74",
|
||||
"mtriple": "riscv64-unknown-linux-gnu",
|
||||
"mcpu": "sifive-u74",
|
||||
"mabi": "lp64d",
|
||||
},
|
||||
)
|
||||
_register_riscv_tag(
|
||||
"riscv/licheepi3a",
|
||||
{
|
||||
"num-cores": 8,
|
||||
"mtriple": "riscv64-unknown-linux-gnu",
|
||||
"mcpu": "spacemit-x60",
|
||||
"mfloat-abi": "hard",
|
||||
"mabi": "lp64d",
|
||||
},
|
||||
)
|
||||
|
||||
_register_riscv_tag(
|
||||
"riscv/spacemit-k3",
|
||||
{
|
||||
"num-cores": 8,
|
||||
"mtriple": "riscv64-unknown-linux-gnu",
|
||||
"mcpu": "spacemit-x100",
|
||||
"mfloat-abi": "hard",
|
||||
"mabi": "lp64d",
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,244 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Target data structure."""
|
||||
|
||||
import tvm_ffi
|
||||
from tvm_ffi import Map
|
||||
from tvm_ffi.core import String
|
||||
|
||||
from tvm.runtime import Device, Object, convert
|
||||
|
||||
from . import _ffi_api
|
||||
|
||||
|
||||
@tvm_ffi.register_object("target.TargetKind")
|
||||
class TargetKind(Object):
|
||||
"""Kind of a compilation target"""
|
||||
|
||||
@property
|
||||
def options(self):
|
||||
"""Returns the dict of available option names and types"""
|
||||
return dict(_ffi_api.ListTargetKindOptions(self))
|
||||
|
||||
@staticmethod
|
||||
def options_from_name(kind_name: str):
|
||||
"""Returns the dict of available option names and types from a name of TargetKind"""
|
||||
return dict(_ffi_api.ListTargetKindOptionsFromName(kind_name))
|
||||
|
||||
|
||||
class TargetFeatures:
|
||||
def __init__(self, target):
|
||||
self.target = target
|
||||
|
||||
def __getattr__(self, name: str):
|
||||
return _ffi_api.TargetGetFeature(self.target, name)
|
||||
|
||||
|
||||
@tvm_ffi.register_object("target.Target")
|
||||
class Target(Object):
|
||||
"""Target device information, use through TVM API.
|
||||
|
||||
Targets can be constructed from:
|
||||
|
||||
- A JSON config dictionary: ``Target({"kind": "cuda", "arch": "sm_80"})``
|
||||
- A tag name: ``Target("nvidia/nvidia-a100")``
|
||||
- A tag with overrides: ``Target({"tag": "nvidia/nvidia-a100", "l2_cache_size_bytes": 12345})``
|
||||
- A kind name: ``Target("cuda")``
|
||||
|
||||
Use ``target.attrs["key"]`` to access target attributes.
|
||||
|
||||
Examples
|
||||
--------
|
||||
.. code-block:: python
|
||||
|
||||
# From a tag
|
||||
target = Target("nvidia/nvidia-a100")
|
||||
|
||||
# From a tag with attribute overrides
|
||||
target = Target({"tag": "qcom/hexagon-v68", "vtcm-capacity": 70000})
|
||||
|
||||
# From a config dictionary
|
||||
target = Target({"kind": "cuda", "arch": "sm_80"})
|
||||
"""
|
||||
|
||||
def __init__(self, target, host=None):
|
||||
"""Construct a TVM target object from
|
||||
1) Raw target string
|
||||
2) Target config dict
|
||||
3) Target tag string
|
||||
4) Tag with overrides dict
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : Union[str, Dict[str, Any]]
|
||||
Can be one of a literal target 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:
|
||||
|
||||
tag : str (optional)
|
||||
A registered tag name (e.g. ``"nvidia/nvidia-a100"``).
|
||||
When ``tag`` is present, the tag's base config is loaded and
|
||||
any additional fields in the dict override the base values.
|
||||
The ``kind`` field is not needed when ``tag`` is specified.
|
||||
kind : str (required unless tag is specified)
|
||||
Which codegen path to use, for example 'llvm' or 'cuda'.
|
||||
keys : List of str (optional)
|
||||
A set of strategies that can be dispatched to. When using
|
||||
"kind=opencl" for example, one could set keys to ["mali", "opencl", "gpu"].
|
||||
device : str (optional)
|
||||
A single key that corresponds to the actual device being run on.
|
||||
This will be effectively appended to the keys.
|
||||
libs : List of str (optional)
|
||||
The set of external libraries to use. For example ['cblas', 'mkl'].
|
||||
system-lib : bool (optional)
|
||||
If True, build a module that contains self registered functions.
|
||||
Useful for environments where dynamic loading like dlopen is banned.
|
||||
mcpu : str (optional)
|
||||
The specific cpu being run on. Serves only as an annotation.
|
||||
model : str (optional)
|
||||
An annotation indicating what model a workload came from.
|
||||
runtime : str (optional)
|
||||
An annotation indicating which runtime to use with a workload.
|
||||
mtriple : str (optional)
|
||||
The llvm triplet describing the target, for example "arm64-linux-android".
|
||||
mattr : List of str (optional)
|
||||
The llvm features to compile with, for example ["+avx512f", "+mmx"].
|
||||
mfloat-abi : str (optional)
|
||||
An llvm setting that is one of 'hard' or 'soft' indicating whether to use
|
||||
hardware or software floating-point operations.
|
||||
mabi : str (optional)
|
||||
An llvm setting. Generate code for the specified ABI, for example "lp64d".
|
||||
host : Union[str, Dict[str, Any]] (optional)
|
||||
Description for target host. Can be recursive. Similar to target.
|
||||
host : Optional[Union[str, Dict[str, Any]]]
|
||||
Similar to target 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 target.
|
||||
"""
|
||||
if isinstance(target, dict | str):
|
||||
target = convert(target)
|
||||
if isinstance(host, dict | str):
|
||||
host = convert(host)
|
||||
if target is None or not isinstance(target, Map | String | Target | str):
|
||||
raise ValueError(f"target has to be a string or dictionary. instead get {type(target)}")
|
||||
if host is not None:
|
||||
if not isinstance(host, Map | String | Target | str):
|
||||
raise ValueError("target host has to be a string or dictionary.")
|
||||
self.__init_handle_by_constructor__(_ffi_api.Target, Target(target), Target(host))
|
||||
else:
|
||||
self.__init_handle_by_constructor__(_ffi_api.Target, target)
|
||||
|
||||
def __enter__(self):
|
||||
_ffi_api.TargetEnterScope(self)
|
||||
return self
|
||||
|
||||
def __exit__(self, ptype, value, trace):
|
||||
_ffi_api.TargetExitScope(self)
|
||||
|
||||
def export(self):
|
||||
return _ffi_api.TargetExport(self)
|
||||
|
||||
def with_host(self, host=None):
|
||||
return _ffi_api.WithHost(self, Target(host))
|
||||
|
||||
@staticmethod
|
||||
def from_device(device: str | Device) -> "Target":
|
||||
"""Detects Target associated with the given device. If the device does not exist,
|
||||
there will be an Error.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dev : Union[str, Device]
|
||||
The device to detect the target for.
|
||||
Supported device types: ["cuda", "metal", "rocm", "vulkan", "opencl", "cpu"]
|
||||
|
||||
Returns
|
||||
-------
|
||||
target : Target
|
||||
The detected target.
|
||||
"""
|
||||
from .detect_target import ( # pylint: disable=import-outside-toplevel
|
||||
detect_target_from_device,
|
||||
)
|
||||
|
||||
return detect_target_from_device(device)
|
||||
|
||||
@staticmethod
|
||||
def current(allow_none=True):
|
||||
"""Returns the current target.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
allow_none : bool
|
||||
Whether allow the current target to be none
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError if current target is not set.
|
||||
"""
|
||||
return _ffi_api.TargetCurrent(allow_none)
|
||||
|
||||
@property
|
||||
def features(self):
|
||||
return TargetFeatures(self)
|
||||
|
||||
def __getattr__(self, name: str):
|
||||
"""Backward-compatible attribute access for target attrs.
|
||||
|
||||
Historically, code accessed target options via attribute syntax
|
||||
(e.g. ``target.arch``). Newer APIs prefer ``target.attrs["arch"]``.
|
||||
"""
|
||||
attrs = self.attrs
|
||||
if name in attrs:
|
||||
value = attrs[name]
|
||||
return str(value) if isinstance(value, String) else value
|
||||
raise AttributeError(f"'Target' object has no attribute '{name}'")
|
||||
|
||||
def get_kind_attr(self, attr_name):
|
||||
"""Get additional attribute about the target kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
attr_name : str
|
||||
The attribute name.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : object
|
||||
The attribute value
|
||||
"""
|
||||
return _ffi_api.TargetKindGetAttr(self.kind, attr_name)
|
||||
|
||||
def get_target_device_type(self):
|
||||
"""Returns the device_type for this target."""
|
||||
return _ffi_api.TargetGetDeviceType(self)
|
||||
|
||||
@staticmethod
|
||||
def list_kinds():
|
||||
"""Returns the list of available target names."""
|
||||
return list(_ffi_api.ListTargetKinds())
|
||||
|
||||
@staticmethod
|
||||
def target_or_current(target):
|
||||
"""Returns target, or the current target in the environment if target is None"""
|
||||
if target is None:
|
||||
target = Target.current()
|
||||
if target is None:
|
||||
raise ValueError("Target is not set in env or passed as argument.")
|
||||
return target
|
||||
@@ -0,0 +1,39 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ruff: noqa: F821
|
||||
"""Python bindings for creating VirtualDevices."""
|
||||
|
||||
import tvm_ffi
|
||||
|
||||
from . import _ffi_api
|
||||
|
||||
|
||||
@tvm_ffi.register_object("target.VirtualDevice")
|
||||
class VirtualDevice(tvm_ffi.core.Object):
|
||||
"""A compile time representation for where data is to be stored at runtime,
|
||||
and how to compile code to compute it."""
|
||||
|
||||
def __init__(self, device=None, target=None, memory_scope="") -> None:
|
||||
if device is None:
|
||||
# The 'unconstrained' device has device type -1 and device id -1.
|
||||
device = tvm.device(-1, -1)
|
||||
self.__init_handle_by_constructor__(
|
||||
_ffi_api.VirtualDevice_ForDeviceTargetAndMemoryScope, device, target, memory_scope
|
||||
)
|
||||
|
||||
def dlpack_device_type(self) -> int:
|
||||
return self.device_type_int
|
||||
Reference in New Issue
Block a user