diff --git a/ethosu/regor/architecture/ethosu85/ethos_u85_register_cs_generator.cpp b/ethosu/regor/architecture/ethosu85/ethos_u85_register_cs_generator.cpp index e0ae155eb01a6596a42cfe54e04d45c270dd48d5..a30bc2479e60311e03c4c443d9044cb6edf5382e 100644 --- a/ethosu/regor/architecture/ethosu85/ethos_u85_register_cs_generator.cpp +++ b/ethosu/regor/architecture/ethosu85/ethos_u85_register_cs_generator.cpp @@ -1885,7 +1885,7 @@ void EthosU85RCSGenerator::GenerateElementwiseOp(HLCStripe *stripe, MemoryAccess GenerateScalingForElementwise(op); GenerateCommon(stripe, useGlobalScale, memoryAccesses); bool ifmIsScalar = IsScalar(op->ifm[0], scalarValue); - bool ifm2IsScalar = IsScalar(op->ifm[1], scalarValue); + bool ifm2IsScalar = !ifmIsScalar && IsScalar(op->ifm[1], scalarValue); GenerateIFM2Precision(op->ifm[1], ifm2Chained, ifm2IsScalar); GenerateIFM2(opType, op->ifm[1], stripe->ifmAreas[1], ifm2IsScalar, scalarValue, ifm2Cb); if ( !ifm2IsScalar && !ifm2Chained ) diff --git a/ethosu/regor/compiler/scheduler.cpp b/ethosu/regor/compiler/scheduler.cpp index 77eda59989948f6ea7cd4ac948f8ff569aca6f77..42fa4aa6e05f8b585e965811ac9f06212bc0bd94 100644 --- a/ethosu/regor/compiler/scheduler.cpp +++ b/ethosu/regor/compiler/scheduler.cpp @@ -859,56 +859,9 @@ bool Scheduler::AllocateAddresses(Schedule *schedule) } -/// @brief Specialised LiveRangeGraph for read only (flash) memory which ignores scalars if possible -class ReadOnlyLiveRangeGraph : public LiveRangeGraph -{ -private: - Architecture *_arch; - -public: - ReadOnlyLiveRangeGraph(Architecture *arch) : _arch(arch) {} - bool ShouldBeIgnored(SchedulerTensor *tens, const MemArea &targetMemory) override - { - // First do the regular check for matching memory type - if ( LiveRangeGraph::ShouldBeIgnored(tens, targetMemory) ) - { - return true; - } - // Memory type correct, check if this tensor is a scalar that can be encoded - // in the command stream for this architecture - auto srcTens = tens->srcTensor; - if ( srcTens && srcTens->StorageShape().Elements() == 1 && srcTens->IsConstant() ) - { - // All consumers must accept this scalar if we are to ignore it - for ( auto op : tens->consumers ) - { - // Find usage of the tensor for this consumer op - TensorUsage usage(TensorUsage::None); - for ( auto input : op->inputs.pairs() ) - { - if ( input.second.tensor.get() == tens ) - { - usage = input.first; - } - } - if ( !_arch->SupportsScalar(op->Type(), tens->dataType, usage) ) - { // This scalar cannot be ignored and must be handled - return false; - } - } - // At this point we have determined that the tensor can be encoded - // as a scalar in the command stream and can safely be ignored - return true; - } - // Not a scalar - cannot be ignored - return false; - } -}; - - void Scheduler::AllocateReadOnlyAddresses(Schedule *schedule, IncrementalLinearAllocator &readOnlyAllocator) { - auto lrGraph = ReadOnlyLiveRangeGraph(_arch); + LiveRangeGraph lrGraph; lrGraph.ExtractLiveRangesFromCascades(_ops, schedule, _arch->ReadonlyMemory(), false); auto totalSize = readOnlyAllocator.Allocate(&lrGraph, NPUTensorAlignment, _options.verboseAllocation); schedule->memoryUsage[_arch->ReadonlyMemory()] = int(totalSize);