The TfLite Pack operator is equivalent to the ArmNN Stack operator
| 4048 | |
| 4049 | /// The TfLite Pack operator is equivalent to the ArmNN Stack operator |
| 4050 | void TfLiteParserImpl::ParsePack(size_t subgraphIndex, size_t operatorIndex) |
| 4051 | { |
| 4052 | CHECK_MODEL(m_Model, subgraphIndex, operatorIndex); |
| 4053 | |
| 4054 | auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex); |
| 4055 | auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex); |
| 4056 | CHECK_VALID_SIZE(outputs.size(), 1); |
| 4057 | |
| 4058 | if (inputs.size() < 1) |
| 4059 | { |
| 4060 | throw ParseException("Pack must have at least one input."); |
| 4061 | } |
| 4062 | |
| 4063 | const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex]; |
| 4064 | const auto* options = operatorPtr->builtin_options.AsPackOptions(); |
| 4065 | |
| 4066 | StackDescriptor desc; |
| 4067 | desc.m_Axis = static_cast<uint32_t>(options->axis); |
| 4068 | desc.m_NumInputs = static_cast<uint32_t>(inputs.size()); |
| 4069 | |
| 4070 | // Use the tensor shape of the first input as the "correct" input shape in the descriptor |
| 4071 | armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0); |
| 4072 | desc.m_InputShape = inputTensorInfo.GetShape(); |
| 4073 | |
| 4074 | auto layerName = fmt::format("Pack:{}:{}", subgraphIndex, operatorIndex); |
| 4075 | IConnectableLayer* layer = m_Network->AddStackLayer(desc, layerName.c_str()); |
| 4076 | |
| 4077 | if (!layer) |
| 4078 | { |
| 4079 | throw NullPointerException(fmt::format("Layer {} pointer is null {}", |
| 4080 | operatorIndex, CHECK_LOCATION().AsString())); |
| 4081 | } |
| 4082 | |
| 4083 | armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {}); |
| 4084 | layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); |
| 4085 | |
| 4086 | auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex)); |
| 4087 | RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes}); |
| 4088 | |
| 4089 | auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex)); |
| 4090 | RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]}); |
| 4091 | } |
| 4092 | |
| 4093 | void TfLiteParserImpl::ParseUnidirectionalSequenceLSTM(size_t subgraphIndex, size_t operatorIndex) |
| 4094 | { |
nothing calls this directly
no test coverage detected