diff --git a/cmake/modules/LibInfo.cmake b/cmake/modules/LibInfo.cmake index 2c23d24b3641..17a56ac439e2 100644 --- a/cmake/modules/LibInfo.cmake +++ b/cmake/modules/LibInfo.cmake @@ -70,6 +70,7 @@ function(add_lib_info src_file) TVM_INFO_USE_AMX="${USE_AMX}" TVM_INFO_USE_DNNL="${USE_DNNL}" TVM_INFO_USE_ETHOSN="${USE_ETHOSN}" + TVM_INFO_USE_ETHOSU="${USE_ETHOSU}" TVM_INFO_USE_FALLBACK_STL_MAP="${USE_FALLBACK_STL_MAP}" TVM_INFO_USE_GRAPH_EXECUTOR_CUDA_GRAPH="${USE_GRAPH_EXECUTOR_CUDA_GRAPH}" TVM_INFO_USE_GRAPH_EXECUTOR="${USE_GRAPH_EXECUTOR}" diff --git a/python/tvm/relay/backend/contrib/ethosu/util.py b/python/tvm/relay/backend/contrib/ethosu/util.py index 6533bab7d272..289754d5c370 100644 --- a/python/tvm/relay/backend/contrib/ethosu/util.py +++ b/python/tvm/relay/backend/contrib/ethosu/util.py @@ -252,10 +252,10 @@ def get_accelerator_config(): return compiler_attrs.accelerator_config -def is_cascader_enabled(): +def is_cascader_enabled() -> bool: """Determine whether the cascader is enabled""" compiler_attrs = tvm.get_global_func("relay.ext.ethos-u.get_compiler_attrs")() - return compiler_attrs.enable_cascader + return bool(compiler_attrs.enable_cascader) def is_copying_constants_disabled() -> bool: @@ -264,10 +264,10 @@ def is_copying_constants_disabled() -> bool: return bool(compiler_attrs.disable_copying_constants) -def is_striping_enabled(): +def is_striping_enabled() -> bool: """Determine whether the cascader is enabled""" compiler_attrs = tvm.get_global_func("relay.ext.ethos-u.get_compiler_attrs")() - return compiler_attrs.enable_striping + return bool(compiler_attrs.enable_striping) def get_arg_count(func): diff --git a/python/tvm/testing/utils.py b/python/tvm/testing/utils.py index 5f8167274862..f29b7c4394c2 100644 --- a/python/tvm/testing/utils.py +++ b/python/tvm/testing/utils.py @@ -963,6 +963,9 @@ def _any_gpu_exists(): # Mark a test as requiring Arm(R) Ethos(TM)-N to run requires_ethosn = Feature("ethosn", "Arm(R) Ethos(TM)-N", cmake_flag="USE_ETHOSN") +# Mark a test as requiring Arm(R) Ethos(TM)-U to run +requires_ethosu = Feature("ethosu", "Arm(R) Ethos(TM)-U", cmake_flag="USE_ETHOSU") + # Mark a test as requiring libtorch to run requires_libtorch = Feature("libtorch", "LibTorch", cmake_flag="USE_LIBTORCH") diff --git a/src/relay/backend/contrib/ethosu/compiler_attrs.cc b/src/relay/backend/contrib/ethosu/compiler_attrs.cc index 237ccecf54d3..a3a09cf1119b 100644 --- a/src/relay/backend/contrib/ethosu/compiler_attrs.cc +++ b/src/relay/backend/contrib/ethosu/compiler_attrs.cc @@ -39,17 +39,17 @@ namespace ethosu { /*! \brief Attributes to store the compiler options for Arm(R) Ethos(TM)-U NPU. */ struct EthosUCompilerConfigNode : public tvm::AttrsNode { String accelerator_config; - bool enable_cascader; - bool enable_striping; + Bool enable_cascader = Bool(false); + Bool enable_striping = Bool(false); Bool disable_copying_constants = Bool(false); String dev_force_block_config; String dev_max_open_plans; String dev_max_closed_plans; String dev_select_proposal_idx; - bool dev_disable_pareto_plans; - bool dev_disable_pareto_proposals; - bool dev_disable_block_culling; - bool dev_cascader_logging; + Bool dev_disable_pareto_plans = Bool(false); + Bool dev_disable_pareto_proposals = Bool(false); + Bool dev_disable_block_culling = Bool(false); + Bool dev_cascader_logging = Bool(false); TVM_DECLARE_ATTRS(EthosUCompilerConfigNode, "ext.attrs.EthosUCompilerConfigNode") { TVM_ATTR_FIELD(accelerator_config) @@ -59,7 +59,10 @@ struct EthosUCompilerConfigNode : public tvm::AttrsNode GetLibInfo() { {"USE_AMX", TVM_INFO_USE_AMX}, {"USE_DNNL", TVM_INFO_USE_DNNL}, {"USE_ETHOSN", TVM_INFO_USE_ETHOSN}, + {"USE_ETHOSU", TVM_INFO_USE_ETHOSU}, {"USE_FALLBACK_STL_MAP", TVM_INFO_USE_FALLBACK_STL_MAP}, {"USE_GRAPH_EXECUTOR_CUDA_GRAPH", TVM_INFO_USE_GRAPH_EXECUTOR_CUDA_GRAPH}, {"USE_GRAPH_EXECUTOR", TVM_INFO_USE_GRAPH_EXECUTOR}, diff --git a/tests/python/contrib/test_ethosu/test_attr_passing.py b/tests/python/contrib/test_ethosu/test_attr_passing.py index a770a2668a01..744ffce8c352 100644 --- a/tests/python/contrib/test_ethosu/test_attr_passing.py +++ b/tests/python/contrib/test_ethosu/test_attr_passing.py @@ -25,23 +25,82 @@ def test_compiler_attr(): config = { "accelerator_config": "ethos-u55-32", + "enable_cascader": True, + "enable_striping": True, + "disable_copying_constants": True, + "dev_force_block_config": "2x4x16", + "dev_max_open_plans": "256", + "dev_max_closed_plans": "128", + "dev_select_proposal_idx": "1", + "dev_disable_pareto_plans": True, + "dev_disable_pareto_proposals": True, + "dev_disable_block_culling": True, + "dev_cascader_logging": True, } with tvm.transform.PassContext(opt_level=3, config={"relay.ext.ethos-u.options": config}): with tvm.target.Target("c"): compiler_attrs = tvm.get_global_func("relay.ext.ethos-u.get_compiler_attrs")() - accel_config_str = compiler_attrs.accelerator_config - assert accel_config_str == config["accelerator_config"] + assert compiler_attrs.accelerator_config == config["accelerator_config"] + assert compiler_attrs.enable_cascader == config["enable_cascader"] + assert compiler_attrs.enable_striping == config["enable_striping"] + assert compiler_attrs.disable_copying_constants == config["disable_copying_constants"] + assert compiler_attrs.dev_force_block_config == config["dev_force_block_config"] + assert compiler_attrs.dev_max_open_plans == config["dev_max_open_plans"] + assert compiler_attrs.dev_max_closed_plans == config["dev_max_closed_plans"] + assert compiler_attrs.dev_select_proposal_idx == config["dev_select_proposal_idx"] + assert compiler_attrs.dev_disable_pareto_plans == config["dev_disable_pareto_plans"] + assert ( + compiler_attrs.dev_disable_pareto_proposals + == config["dev_disable_pareto_proposals"] + ) + assert compiler_attrs.dev_disable_block_culling == config["dev_disable_block_culling"] + assert compiler_attrs.dev_cascader_logging == config["dev_cascader_logging"] def test_compiler_attr_default(): default_config = { "accelerator_config": "ethos-u55-256", + "enable_cascader": False, + "enable_striping": False, + "disable_copying_constants": False, + "dev_force_block_config": "", + "dev_max_open_plans": "8", + "dev_max_closed_plans": "32", + "dev_select_proposal_idx": "-1", + "dev_disable_pareto_plans": False, + "dev_disable_pareto_proposals": False, + "dev_disable_block_culling": False, + "dev_cascader_logging": False, } with tvm.transform.PassContext(opt_level=3): with tvm.target.Target("c"): compiler_attrs = tvm.get_global_func("relay.ext.ethos-u.get_compiler_attrs")() - accel_config_str = compiler_attrs.accelerator_config - assert accel_config_str == default_config["accelerator_config"] + assert compiler_attrs.accelerator_config == default_config["accelerator_config"] + assert compiler_attrs.enable_cascader == default_config["enable_cascader"] + assert compiler_attrs.enable_striping == default_config["enable_striping"] + assert ( + compiler_attrs.disable_copying_constants + == default_config["disable_copying_constants"] + ) + assert compiler_attrs.dev_force_block_config == default_config["dev_force_block_config"] + assert compiler_attrs.dev_max_open_plans == default_config["dev_max_open_plans"] + assert compiler_attrs.dev_max_closed_plans == default_config["dev_max_closed_plans"] + assert ( + compiler_attrs.dev_select_proposal_idx == default_config["dev_select_proposal_idx"] + ) + assert ( + compiler_attrs.dev_disable_pareto_plans + == default_config["dev_disable_pareto_plans"] + ) + assert ( + compiler_attrs.dev_disable_pareto_proposals + == default_config["dev_disable_pareto_proposals"] + ) + assert ( + compiler_attrs.dev_disable_block_culling + == default_config["dev_disable_block_culling"] + ) + assert compiler_attrs.dev_cascader_logging == default_config["dev_cascader_logging"] if __name__ == "__main__": diff --git a/tests/python/driver/tvmc/test_target_options.py b/tests/python/driver/tvmc/test_target_options.py index 8d11e448009d..d3df83f346d6 100644 --- a/tests/python/driver/tvmc/test_target_options.py +++ b/tests/python/driver/tvmc/test_target_options.py @@ -96,6 +96,20 @@ def test_include_known_codegen(): } +@tvm.testing.requires_ethosu +def test_ethosu_compiler_attrs(): + # It is checked that the represented string and boolean types in the + # EthosUCompilerConfigNode structure can be passed via the command line + parser = argparse.ArgumentParser() + generate_target_args(parser) + parsed, _ = parser.parse_known_args( + ["--target-ethos-u-accelerator_config=ethos-u55-32", "--target-ethos-u-enable_cascader=1"] + ) + assert reconstruct_target_args(parsed) == { + "ethos-u": {"accelerator_config": "ethos-u55-32", "enable_cascader": 1}, + } + + def test_skip_target_from_codegen(): parser = argparse.ArgumentParser() generate_target_args(parser)