Skip to content

Commit

Permalink
Merge pull request #866 from khanhlvg:ios-cpp-common-utils-fixes
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 467451277
  • Loading branch information
tflite-support-robot committed Aug 14, 2022
2 parents 5797df4 + c3a7743 commit dd36717
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 22 deletions.
19 changes: 19 additions & 0 deletions tensorflow_lite_support/ios/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,25 @@ objc_library(
],
)

objc_library(
name = "TFLCommonCppUtils",
srcs = [
"sources/TFLCommonCppUtils.mm",
],
hdrs = [
"sources/TFLCommonCppUtils.h",
],
module_name = "TFLCommonCppUtils",
deps = [
":TFLCommon",
"//tensorflow_lite_support/cc:common",
"//tensorflow_lite_support/ios:TFLCommonUtils",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:cord",
],
)

# bazel build -c opt --config=ios_arm64 //tensorflow_lite_support/ios:TensorFlowLiteTaskVision_framework
ios_static_framework(
name = "TensorFlowLiteTaskVision_framework",
Expand Down
11 changes: 11 additions & 0 deletions tensorflow_lite_support/ios/sources/TFLCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,23 @@ typedef NS_ENUM(NSUInteger, TFLSupportErrorCode) {
* E.g.: rotate RGBA buffer to Grayscale buffer by 90 degrees.
*/
TFLSupportErrorCodeImageProcessingInvalidArgumentError,

/**
* Image processing operation failures.
* E.g. libyuv rotation failed for an unknown reason.
*/
TFLSupportErrorCodeImageProcessingBackendError,

/**
* The first error code in TFLSupportErrorCode (for internal use only).
*/
TFLErrorCodeFirst = TFLSupportErrorCodeUnspecifiedError,

/**
* The last error code in TFLSupportErrorCode (for internal use only).
*/
TFLErrorCodeLast = TFLSupportErrorCodeImageProcessingBackendError,

/** kNotFound indicates some requested entity (such as a file or directory) was not found. */
TFLSupportErrorCodeNotFoundError = 900,

Expand Down
38 changes: 38 additions & 0 deletions tensorflow_lite_support/ios/sources/TFLCommonCppUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* Copyright 2022 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#import <Foundation/Foundation.h>

#import "tensorflow_lite_support/ios/sources/TFLCommonUtils.h"

#include "absl/status/status.h" // from @com_google_absl

NS_ASSUME_NONNULL_BEGIN

/** Helper utility for the all tasks which encapsulates common functionality of
* the iOS task library backed by C++ APIs. */
@interface TFLCommonCppUtils : TFLCommonUtils

/**
* Converts an absl status to an NSError.
*
* @param status absl status.
* @param error Pointer to the memory location where the created error should be saved. If `nil`,
* no error will be saved.
*/
+ (BOOL)checkCppError:(const absl::Status &)status toError:(NSError **)error;

@end

NS_ASSUME_NONNULL_END
107 changes: 107 additions & 0 deletions tensorflow_lite_support/ios/sources/TFLCommonCppUtils.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2022 The TensorFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string>

#include "absl/status/status.h" // from @com_google_absl
#include "absl/strings/cord.h" // from @com_google_absl

#include "tensorflow_lite_support/cc/common.h"

#import "tensorflow_lite_support/ios/sources/TFLCommon.h"
#import "tensorflow_lite_support/ios/sources/TFLCommonCppUtils.h"

@implementation TFLCommonCppUtils

+ (BOOL)checkCError:(TfLiteSupportError *)supportError toError:(NSError **)error {
if (!supportError) {
return YES;
}
NSString *description = [NSString stringWithCString:supportError->message
encoding:NSUTF8StringEncoding];
[TFLCommonUtils createCustomError:error withCode:supportError->code description:description];
return NO;
}

+ (BOOL)checkCppError:(const absl::Status &)status toError:(NSError *_Nullable *)error {
if (!status.ok()) {
return YES;
}
// Payload of absl::Status created by the tflite task library stores an appropriate value of the
// enum TfLiteSupportStatus. The integer value corresponding to the TfLiteSupportStatus enum
// stored in the payload is extracted here to later map to the appropriate error code to be
// returned. In cases where the enum is not stored in (payload is NULL or the payload string
// cannot be converted to an integer), we set the error code value to be 1
// (TFLSupportErrorCodeUnspecifiedError of TFLSupportErrorCode used in the iOS library to signify
// any errors not falling into other categories.) Since payload is of type absl::Cord that can be
// type cast into an absl::optional<std::string>, we use the std::stoi function to convert it into
// an integer code if possible.
NSUInteger genericErrorCode = TFLSupportErrorCodeUnspecifiedError;
NSUInteger errorCode;
try {
// Try converting payload to integer if payload is not empty. Otherwise convert a string
// signifying generic error code TFLSupportErrorCodeUnspecifiedError to integer.
errorCode =
(NSUInteger)std::stoi(static_cast<absl::optional<std::string>>(
status.GetPayload(tflite::support::kTfLiteSupportPayload))
.value_or(std::to_string(genericErrorCode)));
} catch (std::invalid_argument &e) {
// If non empty payload string cannot be converted to an integer. Set error code to 1(kError).
errorCode = TFLSupportErrorCodeUnspecifiedError;
}

// If errorCode is outside the range of enum values possible or is
// TFLSupportErrorCodeUnspecifiedError, we try to map the absl::Status::code() to assign
// appropriate TFLSupportErrorCode or TFLSupportErrorCodeUnspecifiedError in default cases. Note:
// The mapping to absl::Status::code() is done to generate a more specific error code than
// TFLSupportErrorCodeUnspecifiedError in cases when the payload can't be mapped to
// TfLiteSupportStatus. This can happen when absl::Status returned by TfLite are in turn returned
// without moodification by TfLite Support Methods.
if (errorCode > TFLErrorCodeLast || errorCode <= TFLErrorCodeFirst) {
switch (status.code()) {
case absl::StatusCode::kInternal:
errorCode = TFLSupportErrorCodeInternalError;
break;
case absl::StatusCode::kInvalidArgument:
errorCode = TFLSupportErrorCodeInvalidArgumentError;
break;
case absl::StatusCode::kNotFound:
errorCode = TFLSupportErrorCodeNotFoundError;
break;
default:
errorCode = TFLSupportErrorCodeUnspecifiedError;
break;
}
}

// Creates the NSEror with the appropriate error
// TFLSupportErrorCode and message. TFLSupportErrorCode has a one to one
// mapping with TfLiteSupportStatus starting from the value 1(TFLSupportErrorCodeUnspecifiedError)
// and hence will be correctly initialized if directly cast from the integer code derived from
// TfLiteSupportStatus stored in its payload. TFLSupportErrorCode omits kOk = 0 of
// TfLiteSupportStatus.
//
// Stores a string including absl status code and message(if non empty) as the
// error message See
// https://github.com/abseil/abseil-cpp/blob/master/absl/status/status.h#L514
// for explanation. absl::Status::message() can also be used but not always
// guaranteed to be non empty.
NSString *description = [NSString
stringWithCString:status.ToString(absl::StatusToStringMode::kWithNoExtraData).c_str()
encoding:NSUTF8StringEncoding];
[TFLCommonUtils createCustomError:error withCode:errorCode description:description];
return NO;
}

@end
7 changes: 5 additions & 2 deletions tensorflow_lite_support/ios/sources/TFLCommonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ limitations under the License.

NS_ASSUME_NONNULL_BEGIN

/** Error domain of TensorFlow Lite Support related errors. */
extern NSString *const TFLSupportTaskErrorDomain;

/** Helper utility for the all tasks which encapsulates common functionality. */
@interface TFLCommonUtils : NSObject

Expand All @@ -30,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
* no error will be saved.
*/
+ (void)createCustomError:(NSError **)error
withCode:(NSInteger)code
withCode:(NSUInteger)code
description:(NSString *)description;

/**
Expand All @@ -44,7 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (void)createCustomError:(NSError **)error
withDomain:(NSString *)domain
code:(NSInteger)code
code:(NSUInteger)code
description:(NSString *)description;

/**
Expand Down
6 changes: 3 additions & 3 deletions tensorflow_lite_support/ios/sources/TFLCommonUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
#import "tensorflow_lite_support/ios/sources/TFLCommon.h"

/** Error domain of TensorFlow Lite Support related errors. */
static NSString *const TFLSupportTaskErrorDomain = @"org.tensorflow.lite.tasks";
NSString *const TFLSupportTaskErrorDomain = @"org.tensorflow.lite.tasks";

@implementation TFLCommonUtils

+ (void)createCustomError:(NSError **)error
withCode:(NSInteger)code
withCode:(NSUInteger)code
description:(NSString *)description {
[TFLCommonUtils createCustomError:error
withDomain:TFLSupportTaskErrorDomain
Expand All @@ -31,7 +31,7 @@ + (void)createCustomError:(NSError **)error

+ (void)createCustomError:(NSError **)error
withDomain:(NSString *)domain
code:(NSInteger)code
code:(NSUInteger)code
description:(NSString *)description {
if (error) {
*error = [NSError errorWithDomain:domain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
==============================================================================*/
#import <XCTest/XCTest.h>

#import "third_party/tensorflow_lite_support/ios/task/core/sources/TFLBaseOptions.h"
#import "third_party/tensorflow_lite_support/ios/task/vision/sources/TFLImageClassifier.h"
#import "third_party/tensorflow_lite_support/ios/task/vision/utils/sources/GMLImage+Utils.h"
#import "tensorflow_lite_support/ios/task/core/sources/TFLBaseOptions.h"
#import "tensorflow_lite_support/ios/task/vision/sources/TFLImageClassifier.h"
#import "tensorflow_lite_support/ios/task/vision/utils/sources/GMLImage+Utils.h"

#include "third_party/tensorflow_lite_support/c/task/vision/utils/frame_buffer_cpp_c_utils.h"
#include "third_party/tensorflow_lite_support/cc/task/vision/image_classifier.h"
#include "tensorflow_lite_support/c/task/vision/utils/frame_buffer_cpp_c_utils.h"
#include "tensorflow_lite_support/cc/task/vision/image_classifier.h"

using ImageClassifier = ::tflite::task::vision::ImageClassifier;
using ImageClassifierOptions = ::tflite::task::vision::ImageClassifierOptions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#import "third_party/tensorflow_lite_support/ios/text/tokenizers/Sources/TFLBertTokenizer.h"
#include "third_party/tensorflow_lite_support/cc/text/tokenizers/bert_tokenizer.h"
#import "third_party/tensorflow_lite_support/ios/text/tokenizers/Sources/TFLTokenizerUtil.h"
#import "third_party/tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.h"
#import "tensorflow_lite_support/ios/text/tokenizers/Sources/TFLBertTokenizer.h"
#include "tensorflow_lite_support/cc/text/tokenizers/bert_tokenizer.h"
#import "tensorflow_lite_support/ios/text/tokenizers/Sources/TFLTokenizerUtil.h"
#import "tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.h"

NS_ASSUME_NONNULL_BEGIN
using BertTokenizerCPP = ::tflite::support::text::tokenizer::BertTokenizer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#import "third_party/tensorflow_lite_support/ios/text/tokenizers/Sources/TFLSentencepieceTokenizer.h"
#include "third_party/absl/memory/memory.h"
#include "third_party/tensorflow_lite_support/cc/text/tokenizers/sentencepiece_tokenizer.h"
#import "third_party/tensorflow_lite_support/ios/text/tokenizers/Sources/TFLTokenizerUtil.h"
#import "third_party/tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.h"
#import "tensorflow_lite_support/ios/text/tokenizers/Sources/TFLSentencepieceTokenizer.h"
#include "absl/memory/memory.h"
#include "tensorflow_lite_support/cc/text/tokenizers/sentencepiece_tokenizer.h"
#import "tensorflow_lite_support/ios/text/tokenizers/Sources/TFLTokenizerUtil.h"
#import "tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.h"

NS_ASSUME_NONNULL_BEGIN
using SentencepieceTokenizerCPP = ::tflite::support::text::tokenizer::SentencePieceTokenizer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#import "third_party/tensorflow_lite_support/ios/text/tokenizers/Sources/TFLTokenizerUtil.h"
#import "tensorflow_lite_support/ios/text/tokenizers/Sources/TFLTokenizerUtil.h"

#import "third_party/tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.h"
#import "tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.h"

using ::tflite::support::text::tokenizer::TokenizerResult;

Expand Down
2 changes: 1 addition & 1 deletion tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#import "third_party/tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.h"
#import "tensorflow_lite_support/ios/utils/Sources/TFLStringUtil.h"

std::string MakeString(NSString* str) { return std::string([str UTF8String]); }

Expand Down

0 comments on commit dd36717

Please sign in to comment.