Skip to content

[Bug] Target(config) rejects canonicalizer-generated feature.* attrs exported by Target::ToConfig() #18882

@mshr-h

Description

@mshr-h

TargetNode::ToConfig() exports canonicalizer-generated feature.* attributes, but TargetInternal::FromConfig() rejects those same keys during reconstruction because they are not part of the target kind schema.

This breaks round-trip reconstruction of exported targets and can also fail when a caller exports a target config, mutates another field, and reconstructs it. MLC-LLM uses this pattern here:
https://github.com/mlc-ai/mlc-llm/blob/345d2e2c96c183fbca4538b268d74cb73485989c/python/mlc_llm/support/auto_target.py#L48-L52

Actual behavior

$ python target_roundtrip_failure.py 
Traceback (most recent call last):
  File "/home/ubuntu/data/project/tvm-example/target_roundtrip_failure.py", line 13, in <module>
    main()
  File "/home/ubuntu/data/project/tvm-example/target_roundtrip_failure.py", line 9, in main
    Target(exported)
  File "/home/ubuntu/data/project/tvm-example/tvm/python/tvm/target/target.py", line 145, in __init__
    self.__init_handle_by_constructor__(_ffi_api.Target, target)
  File "python/tvm_ffi/cython/object.pxi", line 200, in tvm_ffi.core.Object.__init_handle_by_constructor__
  File "python/tvm_ffi/cython/function.pxi", line 123, in tvm_ffi.core.ConstructorCall
  File "python/tvm_ffi/cython/error.pxi", line 163, in tvm_ffi.core.CHECK_CALL
  File "/home/ubuntu/data/project/tvm-example/tvm/src/target/target.cc", line 235, in tvm::TargetInternal::ConstructorDispatcher(tvm::ffi::PackedArgs, tvm::ffi::Any*)
    *rv = Target(opt_map.value());
  File "/home/ubuntu/data/project/tvm-example/tvm/src/target/target.cc", line 125, in tvm::Target::Target(tvm::ffi::Map<tvm::ffi::String, tvm::ffi::Any, void> const&)
    target = TargetInternal::FromConfig(config);
  File "/home/ubuntu/data/project/tvm-example/tvm/src/target/target.cc", line 327, in tvm::TargetInternal::FromConfig(tvm::ffi::Map<tvm::ffi::String, tvm::ffi::Any, void>)
    target->host = ffi::Function(ConstructorDispatcher)(config[kHost]).cast<Target>();
  File "/home/ubuntu/data/project/tvm-example/tvm/src/target/target.cc", line 235, in tvm::TargetInternal::ConstructorDispatcher(tvm::ffi::PackedArgs, tvm::ffi::Any*)
    *rv = Target(opt_map.value());
  File "/home/ubuntu/data/project/tvm-example/tvm/src/target/target.cc", line 125, in tvm::Target::Target(tvm::ffi::Map<tvm::ffi::String, tvm::ffi::Any, void> const&)
    target = TargetInternal::FromConfig(config);
  File "/home/ubuntu/data/project/tvm-example/tvm/src/target/target.cc", line 335, in tvm::TargetInternal::FromConfig(tvm::ffi::Map<tvm::ffi::String, tvm::ffi::Any, void>)
    ffi::Map<ffi::String, ffi::Any> resolved = target->kind->schema_.Resolve(config);
  File "/home/ubuntu/data/project/tvm-example/tvm/include/tvm/ir/config_schema.h", line 152, in tvm::ir::ConfigSchema::ConfigMap tvm::ir::ConfigSchema::Resolve(ConfigMap) const
    TVM_FFI_THROW(ValueError) << os.str();
ValueError: Unknown config option 'feature.has_sme'. Known options: 'kind', 'keys', 'tag', 'device', 'model', 'libs', 'host', 'from_device', 'target_device_type', 'mattr', 'mcpu', 'mtriple', 'mfloat-abi', 'mabi', 'num-cores', 'fast-math', 'fast-math-nnan', 'fast-math-ninf', 'fast-math-nsz', 'fast-math-arcp', 'fast-math-contract', 'fast-math-reassoc', 'opt-level', 'cl-opt', 'jit', 'vector-width'. Target creation from config dict failed: {"kind": "llvm", "tag": "", "keys": ["arm_cpu", "cpu"], "feature.has_sme": 0, "feature.has_matmul_i8": 0, "feature.has_dotprod": 0, "feature.has_fp16_simd": 0, "feature.has_sve": 0, "feature.has_asimd": 1, "feature.is_aarch64": 1, "mtriple": "aarch64-unknown-linux-gnu"}. Target creation from config dict failed: {"kind": "cuda", "tag": "", "keys": ["cuda", "gpu"], "host": {"kind": "llvm", "tag": "", "keys": ["arm_cpu", "cpu"], "feature.has_sme": 0, "feature.has_matmul_i8": 0, "feature.has_dotprod": 0, "feature.has_fp16_simd": 0, "feature.has_sve": 0, "feature.has_asimd": 1, "feature.is_aarch64": 1, "mtriple": "aarch64-unknown-linux-gnu"}, "max_num_threads": 1024, "thread_warp_size": 32, "arch": "sm_53"}

Environment

Any environment details, such as: Operating System, TVM version, etc

Steps to reproduce

from tvm.target import Target

def main() -> None:
    host = Target({"kind": "llvm", "mtriple": "aarch64-unknown-linux-gnu"})
    target = Target({"kind": "cuda", "arch": "sm_53"}, host=host)

    exported = dict(target.export())
    Target(exported)

if __name__ == "__main__":
    main()

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triagePRs or issues that need to be investigated by maintainers to find the right assignees to address ittype: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions