27 for (
unsigned int i = 0; i <
m_Param.GetNumViews(); ++i)
30 std::vector<unsigned int>(
m_Param.GetViewOrigin(i),
m_Param.GetViewOrigin(i) +
m_Param.GetNumDimensions()));
38template<
typename FactoryType>
40 const FactoryType& factory,
45 bool useSubTensors = factory.SupportsSubTensors();
56 std::vector<std::unique_ptr<ITensorHandle>> subTensors;
62 std::set<unsigned int>::iterator axisIt = axis.begin();
65 ((*axisIt == numberOfDimensions - 1) ||
66 (*axisIt == numberOfDimensions - 2));
79 bool canUseSubTensorOnXorY =
true;
80 bool isTensorHandleFactory = std::is_same<armnn::ITensorHandleFactory, FactoryType>::value;
81 if (isTensorHandleFactory)
83 for (
unsigned int it = 0; it < numOutputSlots; ++it)
87 std::vector<Capability> capabilities =
93 canUseSubTensorOnXorY =
false;
94 if (capabilities.empty())
96 canUseSubTensorOnXorY =
true;
100 if (!canUseSubTensorOnXorY)
107 auto CreateSubTensor = [&]()
118 canUseSubTensorOnXorY)
121 return factory.CreateSubTensorHandle(*inputData,
123 this->m_Param.GetViewOrigin(i));
126 return std::unique_ptr<ITensorHandle>();
129 auto subTensor = CreateSubTensor();
132 useSubTensors =
false;
135 subTensors.push_back(std::move(subTensor));
141 for (
auto& subTensor : subTensors)
151 for (
unsigned int i = 0; i <
m_Param.GetNumViews(); ++i)
160 const bool isMemoryManaged)
167 CreateTensors(registry, workloadFactory, isMemoryManaged);
176 CreateTensors(registry, *handleFactory, isMemoryManaged);
187 if (inputShapes.size() !=
m_Param.GetNumViews())
189 throw armnn::Exception(
"inputShapes' and m_NumViews' sizes do not match (\""
190 + std::to_string(inputShapes.size()) +
192 + std::to_string(
m_Param.GetNumViews()) +
"\")");
195 std::vector<TensorShape> outShapes;
197 for (
unsigned int viewIdx = 0; viewIdx <
m_Param.GetNumViews(); viewIdx++)
199 const uint32_t* sizes =
m_Param.GetViewSizes(viewIdx);
212 std::vector<TensorShape> views;
213 for (
unsigned int viewIdx = 0; viewIdx <
m_Param.GetNumViews(); viewIdx++)
215 const uint32_t* sizes =
m_Param.GetViewSizes(viewIdx);
221 if (inferredShapes.size() !=
m_Param.GetNumViews())
224 + std::to_string(inferredShapes.size()) +
226 + std::to_string(
m_Param.GetNumViews()) +
"\")");
229 for (
unsigned int viewIdx = 0; viewIdx <
m_Param.GetNumViews(); viewIdx++)
232 inferredShapes[viewIdx],
#define ARMNN_NO_DEPRECATE_WARN_BEGIN
#define ARMNN_NO_DEPRECATE_WARN_END
Base class for all ArmNN exceptions so that users can filter to just those.
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
virtual void ExecuteStrategy(const IConnectableLayer *layer, const armnn::BaseDescriptor &descriptor, const std::vector< armnn::ConstTensor > &constants, const char *name, const armnn::LayerBindingId id=0)=0
virtual std::vector< Capability > GetCapabilities(const IConnectableLayer *layer, const IConnectableLayer *connectedLayer, CapabilityClass capabilityClass)
static const FactoryId LegacyFactoryId
virtual std::unique_ptr< IWorkload > CreateWorkload(LayerType type, const QueueDescriptor &descriptor, const WorkloadInfo &info) const =0
Backends should implement their own CreateWorkload function with a switch statement.
unsigned int GetNumOutputSlots() const override
Returns the number of connectable output slots.
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
void VerifyShapeInferenceType(const TensorShape &outputShape, ShapeInferenceMethod shapeInferenceMethod)
const std::vector< InputSlot > & GetInputSlots() const
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
std::vector< OutputSlot >::iterator BeginOutputSlots()
LayerType * CloneBase(Graph &graph, Params &&... params) const
std::vector< OutputHandler > m_OutputHandlers
const char * GetName() const override
Returns the name of the layer.
LayerType GetType() const override
Returns the armnn::LayerType of this layer.
void ValidateAndCopyShape(const TensorShape &outputShape, const TensorShape &inferredShape, const ShapeInferenceMethod shapeInferenceMethod, const std::string &layerName, const unsigned int outputSlotIndex=0)
void SetAdditionalInfo(QueueDescriptor &descriptor) const
std::vector< OutputSlot >::iterator EndOutputSlots()
ShapeInferenceMethod m_ShapeInferenceMethod
LayerWithParameters(unsigned int numInputSlots, unsigned int numOutputSlots, LayerType type, const ViewsDescriptor ¶m, const char *name)
WorkloadInfo PrepInfoAndDesc(QueueDescriptor &descriptor) const
const ViewsDescriptor & GetParameters() const override
ITensorHandle * GetData() const
Gets the allocated tensor memory.
const InputSlot * GetConnection(unsigned int index) const override
const TensorInfo & GetTensorInfo() const override
ITensorHandleFactory::FactoryId GetTensorHandleFactoryId() const
void ExecuteStrategy(IStrategy &strategy) const override
Apply a visitor to this layer.
std::vector< TensorShape > InferOutputShapes(const std::vector< TensorShape > &inputShapes) const override
By default returns inputShapes if the number of inputs are equal to number of outputs,...
virtual void CreateTensorHandles(const TensorHandleFactoryRegistry ®istry, const IWorkloadFactory &factory, const bool IsMemoryManaged=true) override
Set the outputs to be appropriate sub tensors of the input if sub tensors are supported otherwise cre...
SplitterLayer(const ViewsDescriptor ¶m, const char *name)
Constructor to create a SplitterLayer.
void ValidateTensorShapesFromInputs() override
Check if the input tensor shape(s) will lead to a valid configuration of SplitterLayer.
SplitterLayer * Clone(Graph &graph) const override
Creates a dynamically-allocated copy of this layer.
virtual std::unique_ptr< IWorkload > CreateWorkload(const IWorkloadFactory &factory) const override
Makes a workload for the Splitter type.
ITensorHandleFactory * GetFactory(ITensorHandleFactory::FactoryId id) const
Find a TensorHandleFactory by Id Returns nullptr if not found.
const TensorShape & GetShape() const
bool IsTypeSpaceMatch(const TensorInfo &other) const
Check that the types are the same and, if quantize, that the quantization parameters are the same.
Copyright (c) 2021 ARM Limited and Contributors.
std::set< unsigned int > ComputeSplitAxis(const armnn::SplitterDescriptor &desc, const TensorShape &input)
Calculates the axis values for split operation.
void Splitter(const SplitterQueueDescriptor &data, std::vector< ITensorHandle * > inputs, std::vector< ITensorHandle * > outputs)
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below.
armnn::TensorInfo GetTensorInfo(unsigned int numberOfBatches, unsigned int numberOfChannels, unsigned int height, unsigned int width, const armnn::DataLayout dataLayout, const armnn::DataType dataType)
std::vector< ViewOrigin > m_ViewOrigins
A ViewsDescriptor for the SplitterLayer.
uint32_t GetNumViews() const
Get the number of views.
uint32_t GetNumDimensions() const
Get the number of dimensions.