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;
54 std::vector<std::string> inputNames;
55 for (
unsigned int i = 0; i < inputs.size(); ++i)
57 if (inputs[i]->GetShape() != stackDescriptor->
m_InputShape)
59 throw armnn::Exception(
"ConvertStackToTosaOperator: Inputs have mismatched shapes.");
62 std::string inputName =
"input" + std::to_string(i) +
"_";
69 tensors.emplace_back(
new TosaSerializationTensor(inputName,
73 inputNames.push_back(inputName);
77 std::string outputName = std::string(
"output0_");
78 tensors.emplace_back(
new TosaSerializationTensor(outputName,
83 bool transposeOpNeeded = (stackDescriptor->
m_Axis == inputTensorRank);
86 std::vector<int32_t> permutationOrder;
87 std::vector<int32_t> reshapeOutputShape;
89 if (transposeOpNeeded)
93 reshapeOutputShape.push_back(
static_cast<int32_t
>(blockOutputShape[stackDescriptor->
m_Axis]));
95 for (
unsigned int d = 0; d < inputTensorRank; d++)
97 permutationOrder.push_back(
static_cast<int32_t
>(d) + 1);
98 reshapeOutputShape.push_back(
static_cast<int32_t
>(blockOutputShape[d]));
100 permutationOrder.push_back(0);
104 concatAxis = stackDescriptor->
m_Axis;
108 std::vector<int32_t> concatOutputShape;
110 for (
unsigned int i = 0; i < inputTensorRank; i++)
112 concatOutputShape.push_back(inputTensorShape[i]);
115 concatOutputShape[concatAxis] *=
static_cast<int>(stackDescriptor->
m_NumInputs);
120 TosaAxisAttribute axisAttribute(
static_cast<int32_t
>(concatAxis));
122 auto* concatOp =
new TosaSerializationOperator(Op_CONCAT,
123 Attribute_AxisAttribute,
127 operators.push_back(concatOp);
129 tensors.emplace_back(
new TosaSerializationTensor(concatOutputName,
136 std::string& reshapeOpOutputName = transposeOpNeeded ? reshapeOutputName : outputName;
138 TosaReshapeAttribute reshapeAttribute = transposeOpNeeded ? reshapeOutputShape : blockOutputShape;
140 auto* reshapeOp =
new TosaSerializationOperator(Op_RESHAPE,
141 Attribute_ReshapeAttribute,
144 {reshapeOpOutputName});
145 operators.push_back(reshapeOp);
147 if (transposeOpNeeded)
150 tensors.emplace_back(
new TosaSerializationTensor(reshapeOutputName,
155 TosaTransposeAttribute transposeAttribute(permutationOrder);
157 TosaSerializationOperator *transposeOp =
new TosaSerializationOperator(Op_TRANSPOSE,
158 Attribute_TransposeAttribute,
162 operators.push_back(transposeOp);
167 return new TosaSerializationBasicBlock(blockName,