Support align_corners and half_pixel_centers for resize ops in NNAPI delegate.

PiperOrigin-RevId: 310835481
Change-Id: I6538e64b453bc3b633a5656a8130ed2139781a94
This commit is contained in:
A. Unique TensorFlower 2020-05-10 19:26:58 -07:00 committed by TensorFlower Gardener
parent b1e6a4eceb
commit 9f320410a2
3 changed files with 36 additions and 27 deletions

View File

@ -300,13 +300,15 @@ VariedShapeSpec/ReshapeOpTest/RegularShapes/1
VariedShapeSpec/ReshapeOpTest/WithStretchDimension/1 VariedShapeSpec/ReshapeOpTest/WithStretchDimension/1
# resize_bilinear_test # resize_bilinear_test
// align_corners & half_pixel_centers are not implemented in NNAPI before API 30
ResizeBilinearOpTest/ResizeBilinearOpTest.+HalfPixelCenters.*,30
// Only models with constant size tensor are accelerated // Only models with constant size tensor are accelerated
ResizeBilinearOpTest/ResizeBilinearOpTest/.+/0,29 ResizeBilinearOpTest/ResizeBilinearOpTest/.+/0,29
# resize_nearest_neighbor_test # resize_nearest_neighbor_test
// align_corners & half_pixel_centers are not implemented in NNAPI. // align_corners & half_pixel_centers are not implemented in NNAPI before API 30
-ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest.+AlignCorners.*,29 ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest.+AlignCorners.*,30
-ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest.+HalfPixelCenters.*,29 ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest.+HalfPixelCenters.*,30
// Only models with constant size tensor are accelerated // Only models with constant size tensor are accelerated
ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest/.+/0,29 ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest/.+/0,29

View File

@ -1648,13 +1648,14 @@ bool NNAPIDelegateKernel::Validate(
} }
auto builtin = auto builtin =
reinterpret_cast<TfLiteResizeBilinearParams*>(node->builtin_data); reinterpret_cast<TfLiteResizeBilinearParams*>(node->builtin_data);
Expect(!builtin->align_corners, if (android_sdk_version <= kMinSdkVersionForNNAPI12) {
NNAPIValidationFailureType::kUnsupportedOperandValue, Expect(!builtin->align_corners,
"NNAPI does not support align_corners == true.", &val_ctx); NNAPIValidationFailureType::kUnsupportedOperandValue,
// TODO(b/147696142): Update when NNAPI delegate can support TF2 behavior. "NNAPI does not support align_corners == true.", &val_ctx);
Expect(!builtin->half_pixel_centers, Expect(!builtin->half_pixel_centers,
NNAPIValidationFailureType::kUnsupportedOperandValue, NNAPIValidationFailureType::kUnsupportedOperandValue,
"NNAPI does not support half_pixel_centers == true.", &val_ctx); "NNAPI does not support half_pixel_centers == true.", &val_ctx);
}
if (android_sdk_version < kMinSdkVersionForNNAPI12) { if (android_sdk_version < kMinSdkVersionForNNAPI12) {
Expect(input.type == kTfLiteFloat32, Expect(input.type == kTfLiteFloat32,
NNAPIValidationFailureType::kUnsupportedInputType, NNAPIValidationFailureType::kUnsupportedInputType,
@ -1668,14 +1669,14 @@ bool NNAPIDelegateKernel::Validate(
ExpectIsFloatOrQuant8Operator(context, node, &val_ctx); ExpectIsFloatOrQuant8Operator(context, node, &val_ctx);
auto builtin = reinterpret_cast<TfLiteResizeNearestNeighborParams*>( auto builtin = reinterpret_cast<TfLiteResizeNearestNeighborParams*>(
node->builtin_data); node->builtin_data);
// TODO(b/149823713): Update when NNAPI delegate can support align_corners if (android_sdk_version <= kMinSdkVersionForNNAPI12) {
// & half_pixel_centers. Expect(!builtin->align_corners,
Expect(!builtin->align_corners, NNAPIValidationFailureType::kUnsupportedOperandValue,
NNAPIValidationFailureType::kUnsupportedOperandValue, "NNAPI does not support align_corners == true.", &val_ctx);
"NNAPI does not support align_corners == true.", &val_ctx); Expect(!builtin->half_pixel_centers,
Expect(!builtin->half_pixel_centers, NNAPIValidationFailureType::kUnsupportedOperandValue,
NNAPIValidationFailureType::kUnsupportedOperandValue, "NNAPI does not support half_pixel_centers == true.", &val_ctx);
"NNAPI does not support half_pixel_centers == true.", &val_ctx); }
} break; } break;
case kTfLiteBuiltinSqueeze: { case kTfLiteBuiltinSqueeze: {
ExpectOpVersion(version, 1, &val_ctx); ExpectOpVersion(version, 1, &val_ctx);
@ -2436,6 +2437,14 @@ TfLiteStatus NNAPIDelegateKernel::Map(
const int output_width = output.dims->data[2]; const int output_width = output.dims->data[2];
mapping_args.builder->AddScalarInt32Operand(output_width); mapping_args.builder->AddScalarInt32Operand(output_width);
mapping_args.builder->AddScalarInt32Operand(output_height); mapping_args.builder->AddScalarInt32Operand(output_height);
auto builtin = reinterpret_cast<TfLiteResizeBilinearParams*>(
mapping_args.node->builtin_data);
if (builtin->align_corners == true ||
builtin->half_pixel_centers == true) {
mapping_args.builder->AddScalarBoolOperand(false); // Use NHWC format
mapping_args.builder->AddScalarBoolOperand(builtin->align_corners);
mapping_args.builder->AddScalarBoolOperand(builtin->half_pixel_centers);
}
*nn_op_type = ANEURALNETWORKS_RESIZE_BILINEAR; *nn_op_type = ANEURALNETWORKS_RESIZE_BILINEAR;
} break; } break;
case kTfLiteBuiltinResizeNearestNeighbor: { case kTfLiteBuiltinResizeNearestNeighbor: {
@ -2445,7 +2454,13 @@ TfLiteStatus NNAPIDelegateKernel::Map(
mapping_args.builder->AddScalarInt32Operand(new_shape.data.i32[1]); mapping_args.builder->AddScalarInt32Operand(new_shape.data.i32[1]);
mapping_args.builder->AddScalarInt32Operand(new_shape.data.i32[0]); mapping_args.builder->AddScalarInt32Operand(new_shape.data.i32[0]);
mapping_args.builder->AddScalarBoolOperand(false); // Use NHWC format mapping_args.builder->AddScalarBoolOperand(false); // Use NHWC format
auto builtin = reinterpret_cast<TfLiteResizeNearestNeighborParams*>(
mapping_args.node->builtin_data);
if (builtin->align_corners == true ||
builtin->half_pixel_centers == true) {
mapping_args.builder->AddScalarBoolOperand(builtin->align_corners);
mapping_args.builder->AddScalarBoolOperand(builtin->half_pixel_centers);
}
*nn_op_type = ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR; *nn_op_type = ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR;
} break; } break;
case kTfLiteBuiltinSqueeze: { case kTfLiteBuiltinSqueeze: {

View File

@ -190,10 +190,6 @@ TEST_P(ResizeBilinearOpTest, TwoDimensionalResizeWithTwoBatches) {
TEST_P(ResizeBilinearOpTest, TEST_P(ResizeBilinearOpTest,
TwoDimensionalResizeWithTwoBatches_HalfPixelCenters) { TwoDimensionalResizeWithTwoBatches_HalfPixelCenters) {
// TODO(b/147696142): Update when NNAPI delegate can support TF2 behavior.
if (SingleOpModel::GetForceUseNnapi()) {
return;
}
ResizeBilinearOpModel m({TensorType_FLOAT32, {2, 2, 2, 1}}, {3, 3}, ResizeBilinearOpModel m({TensorType_FLOAT32, {2, 2, 2, 1}}, {3, 3},
GetParam(), /**half_pixel_centers**/ true); GetParam(), /**half_pixel_centers**/ true);
m.SetInput<float>({ m.SetInput<float>({
@ -253,10 +249,6 @@ TEST_P(ResizeBilinearOpTest, TwoDimensionalResizeWithTwoBatchesUInt8) {
TEST_P(ResizeBilinearOpTest, TEST_P(ResizeBilinearOpTest,
TwoDimensionalResizeWithTwoBatchesUInt8_HalfPixelCenters) { TwoDimensionalResizeWithTwoBatchesUInt8_HalfPixelCenters) {
// TODO(b/147696142): Update when NNAPI delegate can support TF2 behavior.
if (SingleOpModel::GetForceUseNnapi()) {
return;
}
ResizeBilinearOpModel m({TensorType_UINT8, {2, 2, 2, 1}}, {3, 3}, GetParam(), ResizeBilinearOpModel m({TensorType_UINT8, {2, 2, 2, 1}}, {3, 3}, GetParam(),
/**half_pixel_centers**/ true); /**half_pixel_centers**/ true);
m.SetInput<uint8>({ m.SetInput<uint8>({