17 : m_OutputSlot(nullptr)
22 : m_OutputSlot(outputSlot)
24 , m_TensorInfo(tensorInfo)
37 m_OutputSlot->
Connect(inputSlot);
63 SanitizeBiasQuantizationScale(biasInfo, weightInfo, inputInfo);
65 m_TensorInfo = biasInfo;
76 : m_Optional(optional)
80 const void* valueStart,
88 VLOG(DRIVER) <<
"The size of ConstTensor does not match its TensorInfo.";
91 const bool needsSwizzling = (mappings.
GetSize() > 0);
94 m_SwizzledTensorData.resize(tensorInfo.
GetNumBytes());
117 return m_ConstTensor;
124 return &m_ConstTensor;
141 Fail(
"%s: failed to get input operand %i", __func__, inputIndex);
145 if (operand->lifetime != OperandLifeTime::CONSTANT_COPY
146 && operand->lifetime != OperandLifeTime::CONSTANT_REFERENCE
147 && operand->lifetime != OperandLifeTime::NO_VALUE)
162 if (!IsOperandTypeSupportedForTensors(operand.type))
164 VLOG(DRIVER) << __func__ <<
": unsupported operand type for tensor" << operand.type;
170 VLOG(DRIVER) << __func__ <<
": lifetime for input tensor: r" << operand.lifetime;
183 Fail(
"%s: failed to get operand address", __func__);
189 if (overrideTensorShape)
191 tensorInfo.
SetShape(*overrideTensorShape);
194 if (overrideDataType)
201 return ConstTensorPin(tensorInfo, valueStart, operand.location.length, dimensionMappings);
215 Fail(
"%s: failed to get input operand %i", __func__, inputIndex);
219 if (!IsOperandTypeSupportedForTensors(operand->type))
221 VLOG(DRIVER) << __func__ <<
": unsupported operand type for tensor: " << operand->type;
233 const uint32_t operandIndex = operation.inputs[inputIndex];
243 Fail(
"%s: Type 2 dynamic input tensors are not supported", __func__);
248 switch (operand->lifetime)
250 case OperandLifeTime::SUBGRAPH_INPUT:
254 bool isInputSupported =
false;
262 if (!isInputSupported)
264 Fail(
"%s: unsupported input tensor", __func__);
268 [[clang::fallthrough]];
270 case OperandLifeTime::TEMPORARY_VARIABLE:
271 case OperandLifeTime::SUBGRAPH_OUTPUT:
277 const uint32_t operandIndex = operation.inputs[inputIndex];
280 case OperandLifeTime::CONSTANT_COPY:
281 case OperandLifeTime::POINTER:
282 case OperandLifeTime::CONSTANT_REFERENCE:
284 auto constantTensorDataType = operandTensorInfo.
GetDataType();
292 &constantTensorDataType);
295 bool isSupported =
false;
319 Fail(
"%s: invalid operand tensor", __func__);
326 VLOG(DRIVER) << __func__ <<
": unsupported lifetime for input tensor: " << operand->lifetime;
333 VLOG(DRIVER) << __func__ <<
": Operand type: " << e.
m_type <<
" not supported in ArmnnDriver";
345 if (!paddingsOperand)
347 return Fail(
"%s: Could not read paddings operand", __func__);
353 return Fail(
"%s: Operation has invalid paddings operand: expected shape [%d, 2]", __func__, rank);
356 std::vector<int32_t> paddings;
359 return Fail(
"%s: Operation has invalid or unsupported paddings operand", __func__);
363 for (
unsigned int i = 0; i < paddings.size() - 1; i += 2)
365 int paddingBeforeInput = paddings[i];
366 int paddingAfterInput = paddings[i + 1];
368 if (paddingBeforeInput < 0 || paddingAfterInput < 0)
370 return Fail(
"%s: Operation has invalid paddings operand, invalid padding values.", __func__);
373 padDescriptor.
m_PadList.emplace_back((
unsigned int) paddingBeforeInput, (
unsigned int) paddingAfterInput);
381 const char* operationName,
387 VLOG(DRIVER) <<
"Converter::ConvertL2Pool2d()";
392 return Fail(
"%s: Operation Could not read input 0", operationName);
398 return Fail(
"%s: Could not read output 0", __func__);
409 ActivationFn activation;
411 auto inputSize = operation.inputs.size();
426 return Fail(
"%s: Operation has invalid inputs", operationName);
429 if (Is12OrLaterOperand(*output))
437 ::android::nn::PaddingScheme scheme;
445 return Fail(
"%s: Operation has invalid inputs", operationName);
448 if (Is12OrLaterOperand(*output))
461 bool isSupported =
false;
482 validateFunc(outputInfo, isSupported);
494 return Fail(
"%s: AddPooling2dLayer failed", __func__);
505 data,
nullptr, validateFunc, activation);
519 return Fail(
"%s: Operation has invalid inputs", __func__);
526 return Fail(
"%s: Could not read output 0", __func__);
533 return Fail(
"%s: Could not read input 1", __func__);
535 std::vector<int32_t> axis;
538 return Fail(
"%s: Input 1 has invalid values", __func__);
543 std::set<unsigned int> uniqueAxis;
544 std::transform(axis.begin(), axis.end(),
545 std::inserter(uniqueAxis, uniqueAxis.begin()),
546 [rank](
int i) ->
unsigned int { return (i + rank) % rank; });
547 descriptor.
m_vAxis.assign(uniqueAxis.begin(), uniqueAxis.end());
552 return Fail(
"%s: Could not read input 2", __func__);
555 bool isSupported =
false;
571 validateFunc(outputInfo, isSupported);
585 assert(layer !=
nullptr);
593 const char* operationName,
601 return Fail(
"%s: Input 0 is invalid", operationName);
612 bool isSupported =
false;
632 validateFunc(outInfo, isSupported);
665 const size_t weightsInputIndex = operation.inputs[operand_index];
669 for (uint32_t operationIdx = 0; operationIdx <
getMainModel(model).operations.size(); ++operationIdx)
672 const auto& operationIt =
getMainModel(model).operations[operationIdx];
673 if (operationIt.type != OperationType::DEQUANTIZE)
678 size_t outOpIndex = weightsInputIndex + 1;
679 for (
size_t i = 0; outOpIndex != weightsInputIndex && i < operationIt.outputs.size(); ++i)
681 outOpIndex = operationIt.outputs[i];
684 if (outOpIndex != weightsInputIndex)
706 const uint8_t* quantizedBuffer =
reinterpret_cast<const uint8_t*
>(startValue);
707 size_t dequantizedBufferLength = operand->location.length;
708 const float quantizationScale = operand->scale;
710 auto dequantizedBuffer = std::make_unique<float[]>(dequantizedBufferLength + 1);
711 for (
size_t i = 0; i < dequantizedBufferLength; ++i)
713 float* dstPtr = dequantizedBuffer.get();
715 *dstPtr++ = quantizedBuffer[i] * quantizationScale;
720 operand->dimensions.data(),
723 return { std::move(dequantizedBuffer), dequantizedBufferLength *
sizeof(float),
724 std::move(tensorInfo),
750 operation, operandIndex, model, data,
g_DontPermute,
nullptr, optional);
756 std::get<2>(dequantized), std::get<0>(dequantized).get(), std::get<1>(dequantized),
g_DontPermute);
763 PaddingScheme& outPaddingScheme,
767 int32_t paddingSchemeAsInt;
768 if (!
GetInputInt32(operation, inputIndex, paddingSchemeAsInt, model, data))
770 return Fail(
"%s: failed to get padding scheme input value", __func__);
773 outPaddingScheme =
static_cast<::android::nn::PaddingScheme
>(paddingSchemeAsInt);
782 const void* valueStart =
nullptr;
783 switch (operand.lifetime)
785 case OperandLifeTime::CONSTANT_COPY:
787 valueStart = model.operandValues.data() + operand.location.offset;
790 case OperandLifeTime::POINTER:
793 valueStart = std::get<const void*>(operand.location.pointer);
796 case OperandLifeTime::CONSTANT_REFERENCE:
802 case OperandLifeTime::NO_VALUE:
807 valueStart =
nullptr;
814 VLOG(DRIVER) << __func__ <<
": unsupported/invalid operand lifetime:: " << operand.lifetime;
815 valueStart =
nullptr;
823 std::vector<int32_t>& outValues,
827 if (operand.type != OperandType::TENSOR_INT32)
829 VLOG(DRIVER) << __func__ <<
": invalid operand type: " << operand.type;
836 VLOG(DRIVER) << __func__ <<
": failed to get operand address " << operand.type;
841 const uint32_t numBytes = operand.location.length;
842 if (numBytes %
sizeof(int32_t) != 0)
844 return Fail(
"%s: invalid number of bytes: %i, expected to be a multiple of %i",
845 __func__, numBytes,
sizeof(int32_t));
848 outValues.resize(numBytes /
sizeof(int32_t));
849 memcpy(outValues.data(), startAddress, numBytes);
864 if (!IsBool(*operand))
875 if (*(
static_cast<const bool*
>(valueAddress)))
886 ActivationFn activation,
896 if (activation != ActivationFn::kActivationNone)
901 case ActivationFn::kActivationRelu:
906 case ActivationFn::kActivationRelu1:
909 activationDesc.
m_A = 1.0f;
910 activationDesc.
m_B = -1.0f;
913 case ActivationFn::kActivationRelu6:
916 activationDesc.
m_A = 6.0f;
919 case ActivationFn::kActivationSigmoid:
924 case ActivationFn::kActivationTanh:
927 activationDesc.
m_A = 1.0f;
928 activationDesc.
m_B = 1.0f;
933 Fail(
"%s: Invalid activation enum value %i", __func__, activation);
938 bool isSupported =
false;
953 activationLayer = data.
m_Network->AddActivationLayer(activationDesc);
960 return activationLayer;
964 uint32_t operationOutputIndex,
966 uint32_t layerOutputIndex,
971 const ActivationFn& activationFunction,
972 bool inferOutputShapes)
975 if ((outputOperand ==
nullptr) || (operationOutputIndex >= layer.
GetNumOutputSlots()))
981 if (overrideOutputInfo ==
nullptr)
990 bool isSupported =
false;
994 for (
unsigned int inputSlotIndex = 0; inputSlotIndex < layer.
GetNumInputSlots(); ++inputSlotIndex)
1008 for (
unsigned int inputSlotIndex = 0; inputSlotIndex < layer.
GetNumInputSlots(); ++inputSlotIndex)
1016 const uint32_t operandIndex = operation.outputs[operationOutputIndex];
1018 if (activationFunction != ActivationFn::kActivationNone)
1026 return Fail(
"%s: ProcessActivation failed", __func__);
1042 VLOG(DRIVER) <<
"ConversionUtils::IsConnectedToDequantize()";
1047 VLOG(DRIVER) <<
"ConversionUtils::IsConnectedToDequantize() ioutputSlot is valid.";
1052 VLOG(DRIVER) <<
"ConversionUtils::IsConnectedToDequantize() connected to Dequantize Layer.";
1057 VLOG(DRIVER) <<
"ConversionUtils::IsConnectedToDequantize() Dequantize Layer has a connection.";
1062 VLOG(DRIVER) <<
"ConversionUtils::IsConnectedToDequantize() Dequantize Layer connected to Constant";