blob: 3676ce5b8d19f7f0381dbce151040e87fcdf7c79 [file] [edit]
/*
* Copyright 2024 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "delegate/sample/delegate.h"
#include <memory>
#include "common/simple_async_delegate.h"
#include "delegate/sample/kernel.h"
#include "tensorflow/lite/core/c/builtin_op_data.h"
#include "tensorflow/lite/core/c/c_api.h"
#include "tensorflow/lite/core/c/c_api_opaque.h"
#include "tensorflow/lite/core/c/common.h"
namespace tflite::cros {
bool CrosSampleDelegate::IsNodeSupportedByDelegate(
const TfLiteRegistrationExternal* registration_external,
const TfLiteOpaqueNode* node,
TfLiteOpaqueContext* context) const {
TfLiteBuiltinOperator builtin_operator =
TfLiteRegistrationExternalGetBuiltInCode(registration_external);
void* builtin_data = TfLiteOpaqueNodeGetBuiltinData(node);
// The delegate only supports addition and subtraction operations without
// fused activation.
switch (builtin_operator) {
case kTfLiteBuiltinAdd: {
auto* params = reinterpret_cast<TfLiteAddParams*>(builtin_data);
if (params == nullptr || params->activation != kTfLiteActNone) {
return false;
}
break;
}
case kTfLiteBuiltinSub: {
auto* params = reinterpret_cast<TfLiteSubParams*>(builtin_data);
if (params == nullptr || params->activation != kTfLiteActNone) {
return false;
}
break;
}
default: {
return false;
}
}
// The delegate only accepts two inputs with float32 type.
if (TfLiteOpaqueNodeNumberOfInputs(node) != 2) {
return false;
}
const auto* input1 = TfLiteOpaqueNodeGetInput(context, node, 0);
const auto* input2 = TfLiteOpaqueNodeGetInput(context, node, 1);
if (input1 == nullptr || TfLiteOpaqueTensorType(input1) != kTfLiteFloat32 ||
input2 == nullptr || TfLiteOpaqueTensorType(input2) != kTfLiteFloat32) {
return false;
}
// The delegate doesn't support broadcasting; it requires both inputs to have
// the same shape.
int num_dims = TfLiteOpaqueTensorNumDims(input1);
if (num_dims != TfLiteOpaqueTensorNumDims(input2)) {
return false;
}
for (int i = 0; i < num_dims; ++i) {
if (TfLiteOpaqueTensorDim(input1, i) != TfLiteOpaqueTensorDim(input2, i)) {
return false;
}
}
return true;
}
TfLiteStatus CrosSampleDelegate::Initialize(TfLiteOpaqueContext* context) {
return kTfLiteOk;
}
const char* CrosSampleDelegate::Name() const {
return kName;
}
std::unique_ptr<SimpleAsyncDelegateKernelInterface>
CrosSampleDelegate::CreateDelegateKernelInterface() {
return std::make_unique<CrosSampleDelegateKernel>();
}
} // namespace tflite::cros