diff --git a/tensorflow/lite/delegates/nnapi/acceleration_test_list.cc b/tensorflow/lite/delegates/nnapi/acceleration_test_list.cc index 01d56fb2102..cc9e049123e 100644 --- a/tensorflow/lite/delegates/nnapi/acceleration_test_list.cc +++ b/tensorflow/lite/delegates/nnapi/acceleration_test_list.cc @@ -300,13 +300,15 @@ VariedShapeSpec/ReshapeOpTest/RegularShapes/1 VariedShapeSpec/ReshapeOpTest/WithStretchDimension/1 # 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 ResizeBilinearOpTest/ResizeBilinearOpTest/.+/0,29 # resize_nearest_neighbor_test -// align_corners & half_pixel_centers are not implemented in NNAPI. --ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest.+AlignCorners.*,29 --ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest.+HalfPixelCenters.*,29 +// align_corners & half_pixel_centers are not implemented in NNAPI before API 30 +ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest.+AlignCorners.*,30 +ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest.+HalfPixelCenters.*,30 // Only models with constant size tensor are accelerated ResizeNearestNeighborOpTest/ResizeNearestNeighborOpTest/.+/0,29 diff --git a/tensorflow/lite/delegates/nnapi/nnapi_delegate.cc b/tensorflow/lite/delegates/nnapi/nnapi_delegate.cc index 67e038e962e..e790d423434 100644 --- a/tensorflow/lite/delegates/nnapi/nnapi_delegate.cc +++ b/tensorflow/lite/delegates/nnapi/nnapi_delegate.cc @@ -1648,13 +1648,14 @@ bool NNAPIDelegateKernel::Validate( } auto builtin = reinterpret_cast(node->builtin_data); - Expect(!builtin->align_corners, - NNAPIValidationFailureType::kUnsupportedOperandValue, - "NNAPI does not support align_corners == true.", &val_ctx); - // TODO(b/147696142): Update when NNAPI delegate can support TF2 behavior. - Expect(!builtin->half_pixel_centers, - NNAPIValidationFailureType::kUnsupportedOperandValue, - "NNAPI does not support half_pixel_centers == true.", &val_ctx); + if (android_sdk_version <= kMinSdkVersionForNNAPI12) { + Expect(!builtin->align_corners, + NNAPIValidationFailureType::kUnsupportedOperandValue, + "NNAPI does not support align_corners == true.", &val_ctx); + Expect(!builtin->half_pixel_centers, + NNAPIValidationFailureType::kUnsupportedOperandValue, + "NNAPI does not support half_pixel_centers == true.", &val_ctx); + } if (android_sdk_version < kMinSdkVersionForNNAPI12) { Expect(input.type == kTfLiteFloat32, NNAPIValidationFailureType::kUnsupportedInputType, @@ -1668,14 +1669,14 @@ bool NNAPIDelegateKernel::Validate( ExpectIsFloatOrQuant8Operator(context, node, &val_ctx); auto builtin = reinterpret_cast( node->builtin_data); - // TODO(b/149823713): Update when NNAPI delegate can support align_corners - // & half_pixel_centers. - Expect(!builtin->align_corners, - NNAPIValidationFailureType::kUnsupportedOperandValue, - "NNAPI does not support align_corners == true.", &val_ctx); - Expect(!builtin->half_pixel_centers, - NNAPIValidationFailureType::kUnsupportedOperandValue, - "NNAPI does not support half_pixel_centers == true.", &val_ctx); + if (android_sdk_version <= kMinSdkVersionForNNAPI12) { + Expect(!builtin->align_corners, + NNAPIValidationFailureType::kUnsupportedOperandValue, + "NNAPI does not support align_corners == true.", &val_ctx); + Expect(!builtin->half_pixel_centers, + NNAPIValidationFailureType::kUnsupportedOperandValue, + "NNAPI does not support half_pixel_centers == true.", &val_ctx); + } } break; case kTfLiteBuiltinSqueeze: { ExpectOpVersion(version, 1, &val_ctx); @@ -2436,6 +2437,14 @@ TfLiteStatus NNAPIDelegateKernel::Map( const int output_width = output.dims->data[2]; mapping_args.builder->AddScalarInt32Operand(output_width); mapping_args.builder->AddScalarInt32Operand(output_height); + auto builtin = reinterpret_cast( + 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; } break; 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[0]); mapping_args.builder->AddScalarBoolOperand(false); // Use NHWC format - + auto builtin = reinterpret_cast( + 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; } break; case kTfLiteBuiltinSqueeze: { diff --git a/tensorflow/lite/kernels/resize_bilinear_test.cc b/tensorflow/lite/kernels/resize_bilinear_test.cc index 5cbba026010..d4d414ae29c 100644 --- a/tensorflow/lite/kernels/resize_bilinear_test.cc +++ b/tensorflow/lite/kernels/resize_bilinear_test.cc @@ -190,10 +190,6 @@ TEST_P(ResizeBilinearOpTest, TwoDimensionalResizeWithTwoBatches) { TEST_P(ResizeBilinearOpTest, 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}, GetParam(), /**half_pixel_centers**/ true); m.SetInput({ @@ -253,10 +249,6 @@ TEST_P(ResizeBilinearOpTest, TwoDimensionalResizeWithTwoBatchesUInt8) { TEST_P(ResizeBilinearOpTest, 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(), /**half_pixel_centers**/ true); m.SetInput({