15 const std::vector<const TensorInfo*>& inputs,
16 const std::vector<const TensorInfo*>& outputs,
20 "ConvertStackToTosaOperator: Stack must have at least one input");
23 "ConvertStackToTosaOperator: Stack must have only one output");
26 "ConvertStackToTosaOperator: Scalar / Rank 0 input not supported");
28 const auto inputTensorRank = inputs[0]->GetNumDimensions();
31 "ConvertStackToTosaOperator: Scalar / Rank 0 input not supported");
34 if (stackDescriptor->
m_Axis > inputTensorRank)
36 throw armnn::Exception(
"ConvertStackToTosaOperator: Axis is out of a valid range.");
40 if (outputs[0]->GetNumDimensions() != inputTensorRank + 1)
42 throw armnn::Exception(
"ConvertStackToTosaOperator: Output shape mismatch.");
45 auto inputDType =
ArmNNToDType(inputs[0]->GetDataType());
47 std::vector<TosaSerializationTensor*> tensors;
48 std::vector<TosaSerializationOperator*> operators;
50 std::string outputName = std::string(
"output0_");
56 std::vector<std::string> inputNames;
57 for (
unsigned int i = 0; i < inputs.size(); ++i)
59 if (inputs[i]->GetShape() != stackDescriptor->
m_InputShape)
61 throw armnn::Exception(
"ConvertStackToTosaOperator: Inputs have mismatched shapes.");
64 std::string inputName =
"input_" + std::to_string(i);
72 if(inputName.find(
"input_") != std::string::npos)
74 tensors.emplace_back(
new TosaSerializationTensor(inputName,
80 inputNames.push_back(inputName);
85 tensors.emplace_back(
new TosaSerializationTensor(outputName,
90 bool transposeOpNeeded = (stackDescriptor->
m_Axis == inputTensorRank);
93 std::vector<int32_t> permutationOrder;
94 std::vector<int32_t> reshapeOutputShape;
96 if (transposeOpNeeded)
100 reshapeOutputShape.push_back(
static_cast<int32_t
>(blockOutputShape[stackDescriptor->
m_Axis]));
102 for (
unsigned int d = 0; d < inputTensorRank; d++)
104 permutationOrder.push_back(
static_cast<int32_t
>(d) + 1);
105 reshapeOutputShape.push_back(
static_cast<int32_t
>(blockOutputShape[d]));
107 permutationOrder.push_back(0);
111 concatAxis = stackDescriptor->
m_Axis;
115 std::vector<int32_t> concatOutputShape;
117 for (
unsigned int i = 0; i < inputTensorRank; i++)
119 concatOutputShape.push_back(inputTensorShape[i]);
122 concatOutputShape[concatAxis] *=
static_cast<int>(stackDescriptor->
m_NumInputs);
127 TosaAxisAttribute axisAttribute(
static_cast<int32_t
>(concatAxis));
129 auto* concatOp =
new TosaSerializationOperator(Op_CONCAT,
130 Attribute_AxisAttribute,
134 operators.push_back(concatOp);
136 tensors.emplace_back(
new TosaSerializationTensor(concatOutputName,
143 std::string& reshapeOpOutputName = transposeOpNeeded ? reshapeOutputName : outputName;
145 TosaReshapeAttribute reshapeAttribute = transposeOpNeeded ? reshapeOutputShape : blockOutputShape;
147 auto* reshapeOp =
new TosaSerializationOperator(Op_RESHAPE,
148 Attribute_ReshapeAttribute,
151 {reshapeOpOutputName});
152 operators.push_back(reshapeOp);
154 if (transposeOpNeeded)
157 tensors.emplace_back(
new TosaSerializationTensor(reshapeOutputName,
162 TosaTransposeAttribute transposeAttribute(permutationOrder);
164 TosaSerializationOperator *transposeOp =
new TosaSerializationOperator(Op_TRANSPOSE,
165 Attribute_TransposeAttribute,
169 operators.push_back(transposeOp);
174 return new TosaSerializationBasicBlock(blockName,
#define ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(_cond, _str)
TosaSerializationBasicBlock * ConvertStackToTosaOperator(const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const StackDescriptor *stackDescriptor)
std::string GenerateUniqueOutputName(const Layer &layer, uint32_t layerSlot=0)
const std::string mainName
DType ArmNNToDType(const DataType &type)
std::vector< int32_t > GetTosaTensorShape(const TensorShape &shape)
std::string GenerateUniqueInputName(const armnn::InputSlot &slot)
std::string GetUniqueTosaMappingID()
Base class for all ArmNN exceptions so that users can filter to just those.
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
A StackDescriptor for the StackLayer.
TensorShape m_InputShape
Required shape of all input tensors.
uint32_t m_Axis
0-based axis along which to stack the input tensors.
uint32_t m_NumInputs
Number of input tensors.