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

[ETHOSN] Add support for experimental compiler option #13410

Merged
merged 2 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/relay/backend/contrib/ethosn/codegen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -713,9 +713,17 @@ runtime::ethosn::OrderedCompiledNetwork EthosnCompiler::CompileEthosnFunc(const
auto network_with_ids = ConstructNetwork(mod, gvar, func);
// Now set the required build flags
sl::CompilationOptions options = CreateOptions();
// Finally compile the network
// Set the experimental compiler if enabled, for now this is not part of the
Copy link
Contributor

Choose a reason for hiding this comment

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

Setting and unsetting the variable from here means that its being set multiple times during the compilation. Is there a better place from where it gets set/unset only once?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

my thinking was to reduce the scope of the environment variable to the support library, since its not prefixed in any way there's always the (small!) chance the same variable can be used elsewhere. We could move the scope to the NPU codegen instead

Copy link
Contributor

Choose a reason for hiding this comment

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

Another option could be to look for this option from just the tvmc frontend functions and set/unset it from python for the entire invocation of the tvmc. Maybe that leaves the EthosN code cleaner. Are there any downsides of doing that though? 🤔

// support library compilation options.
bool experimental_compiler = GetCompilerAttrs()->experimental_compiler;
if (experimental_compiler) {
setenv("FORCE_EXPERIMENTAL_COMPILER", "1", 1);
}
std::vector<std::unique_ptr<sl::CompiledNetwork>> compiled_networks =
sl::Compile(*network_with_ids.network, options);
if (experimental_compiler) {
unsetenv("FORCE_EXPERIMENTAL_COMPILER");
}
ICHECK_GE(compiled_networks.size(), 1) << "Ethos-N compiler failed to compile network";
auto compiled_network = std::move(compiled_networks[0]);
// Determine the order that the inputs/outputs are in and how that corresponds to the
Expand Down
4 changes: 4 additions & 0 deletions src/relay/backend/contrib/ethosn/codegen_ethosn.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ struct EthosnCompilerConfigNode : public tvm::AttrsNode<EthosnCompilerConfigNode
bool disable_winograd;
String debug_dir;
bool inline_non_compute_intensive_partitions;
bool experimental_compiler;

TVM_DECLARE_ATTRS(EthosnCompilerConfigNode, "ext.attrs.EthosnCompilerConfigNode") {
TVM_ATTR_FIELD(variant).describe("See Ethos-N documentation.").set_default("n78");
Expand Down Expand Up @@ -285,6 +286,9 @@ struct EthosnCompilerConfigNode : public tvm::AttrsNode<EthosnCompilerConfigNode
"Ethos(TM)-N that are deemed 'non-compute-intensive'. The inlined functions will "
"continue through TVM's standard compilation flow.")
.set_default(true);
TVM_ATTR_FIELD(experimental_compiler)
.describe("An exprimental cascading compiler for Arm(R) Ethos(TM)-N.")
lhutton1 marked this conversation as resolved.
Show resolved Hide resolved
.set_default(false);
}
};

Expand Down
54 changes: 54 additions & 0 deletions tests/python/contrib/test_ethosn/test_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,57 @@ def test_compile_with_unsupported_variant():

with pytest.raises(tvm.TVMError, match=r"Unknown NPU type"):
tei.build_and_run(mod, inputs, 1, {}, True, additional_config_args=additional_config_args)


@requires_ethosn
def test_experimental_compiler(capfd):
"""Test compilation with the experimental compiler."""
dtype = "int8"
input_shape = (1, 2, 2, 2)

x = relay.var("x", shape=input_shape, dtype=dtype)
y = relay.reshape(x, newshape=(1, 1, 1, 8))
mod = tei.make_ethosn_partition(y)

additional_config_args = {
"variant": "n78",
"experimental_compiler": True,
lhutton1 marked this conversation as resolved.
Show resolved Hide resolved
"inline_non_compute_intensive_partitions": False,
}

tei.build(mod, {}, True, additional_config_args=additional_config_args)

# Check for hints that the experimental compiler was activated.
# The support library logs a warning to say the the experimental
# compiler is in use. Check that this warning was logged.
captured = capfd.readouterr()
assert (
"WARNING: Experimental Compiler in use." in captured.err
), "Experimental compiler was not activated."


@requires_ethosn
def test_without_experimental_compiler(capfd):
"""Test compilation when the experimental compiler is not enabled."""
dtype = "int8"
input_shape = (1, 2, 2, 2)

x = relay.var("x", shape=input_shape, dtype=dtype)
y = relay.reshape(x, newshape=(1, 1, 1, 8))
mod = tei.make_ethosn_partition(y)

additional_config_args = {
"variant": "n78",
"experimental_compiler": False,
"inline_non_compute_intensive_partitions": False,
}

tei.build(mod, {}, True, additional_config_args=additional_config_args)

# Check for hints that the experimental compiler was activated.
# The support library logs a warning to say the the experimental
# compiler is in use. Check that this warning was logged.
captured = capfd.readouterr()
assert (
"WARNING: Experimental Compiler in use." not in captured.err
), "Experimental compiler was enabled when it is not expected to be."