diff --git a/backends/nxp/runtime/NeutronBackend.cpp b/backends/nxp/runtime/NeutronBackend.cpp index 17c5066f146..6eb7941949f 100644 --- a/backends/nxp/runtime/NeutronBackend.cpp +++ b/backends/nxp/runtime/NeutronBackend.cpp @@ -523,6 +523,16 @@ class NeutronBackend final : public PyTorchBackendInterface { } } + // Resume (clock-ungate) the NPU immediately before inference and suspend it + // again immediately after, so its clock only runs during compute +#ifdef NEUTRON_NPU_POWER_GATING + NeutronError resumeRC = neutronResume(); + if (resumeRC != ENONE) { + ET_LOG(Error, "neutronResume failed with error code %ld", resumeRC); + return Error::InvalidProgram; + } +#endif + #ifdef ET_EVENT_TRACER_ENABLED // Save ticks before neutron compute to measure how much time profiling dump // takes @@ -530,6 +540,21 @@ class NeutronBackend final : public PyTorchBackendInterface { #endif // Run neutron compute. NeutronError neutronRC = neutronRunBlocking(cfg->nmh, &cfg->dcfg); +#ifdef ET_EVENT_TRACER_ENABLED + // Save ticks after neutron compute to measure how much time profiling dump + // takes + et_timestamp_t stop_ticks = ::executorch::runtime::pal_current_ticks(); +#endif + +#ifdef NEUTRON_NPU_POWER_GATING + // Suspend (clock-gate) the NPU again regardless of the run result; a failed + // suspend only wastes power, so it must not fail the inference. + NeutronError suspendRC = neutronSuspend(); + if (suspendRC != ENONE) { + ET_LOG(Error, "neutronSuspend failed with error code %ld", suspendRC); + } +#endif + if (neutronRC != ENONE) { ET_LOG( Error, @@ -537,11 +562,6 @@ class NeutronBackend final : public PyTorchBackendInterface { neutronRC); return Error::InvalidProgram; } -#ifdef ET_EVENT_TRACER_ENABLED - // Save ticks after neutron compute to measure how much time profiling dump - // takes - et_timestamp_t stop_ticks = ::executorch::runtime::pal_current_ticks(); -#endif // Transpose outputs. for (int i = 0; i < cfg->numOutputs; i++) { diff --git a/backends/nxp/runtime/targets.bzl b/backends/nxp/runtime/targets.bzl index f15495efdb7..9238fb2a487 100644 --- a/backends/nxp/runtime/targets.bzl +++ b/backends/nxp/runtime/targets.bzl @@ -11,7 +11,9 @@ def define_common_targets(): ], link_whole = True, # Constructor needed for backend registration. - compiler_flags = ["-Wno-global-constructors", "-fno-rtti", "-DNO_HEAP_USAGE"], + # NEUTRON_NPU_POWER_GATING clock-gates the NPU around each inference + # (neutronResume/neutronSuspend in NeutronBackend.cpp). + compiler_flags = ["-Wno-global-constructors", "-fno-rtti", "-DNO_HEAP_USAGE", "-DNEUTRON_NPU_POWER_GATING"], labels = [ci.skip_target()], visibility = ["PUBLIC"], deps = [