Update Objective-C API (#7675)

- Add session/run configuration
- Add additional supported tensor data types
- Clean up
This commit is contained in:
Edward Chen 2021-05-13 18:47:22 -07:00 committed by GitHub
parent 56e993a434
commit 19704aedbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 478 additions and 83 deletions

View file

@ -40,7 +40,8 @@ set(onnxruntime_objc_headers
"${OBJC_ROOT}/include/ort_enums.h"
"${OBJC_ROOT}/include/ort_env.h"
"${OBJC_ROOT}/include/ort_session.h"
"${OBJC_ROOT}/include/ort_value.h")
"${OBJC_ROOT}/include/ort_value.h"
)
file(GLOB onnxruntime_objc_srcs
"${OBJC_ROOT}/src/*.h"

View file

@ -206,9 +206,9 @@ typedef void(ORT_API_CALL* OrtLoggingFunction)(
void* param, OrtLoggingLevel severity, const char* category, const char* logid, const char* code_location,
const char* message);
// Set Graph optimization level.
// Refer https://github.com/microsoft/onnxruntime/blob/master/docs/ONNX_Runtime_Graph_Optimizations.md
// for in-depth undersrtanding of Graph Optimizations in ORT
// Graph optimization level.
// Refer to https://www.onnxruntime.ai/docs/resources/graph-optimizations.html
// for an in-depth understanding of Graph Optimizations in ORT
typedef enum GraphOptimizationLevel {
ORT_DISABLE_ALL = 0,
ORT_ENABLE_BASIC = 1,

View file

@ -32,7 +32,22 @@ typedef NS_ENUM(int32_t, ORTValueType) {
typedef NS_ENUM(int32_t, ORTTensorElementDataType) {
ORTTensorElementDataTypeUndefined,
ORTTensorElementDataTypeFloat,
ORTTensorElementDataTypeInt8,
ORTTensorElementDataTypeUInt8,
ORTTensorElementDataTypeInt32,
ORTTensorElementDataTypeUInt32,
};
/**
* The ORT graph optimization levels.
* See here for more details:
* https://www.onnxruntime.ai/docs/resources/graph-optimizations.html
*/
typedef NS_ENUM(int32_t, ORTGraphOptimizationLevel) {
ORTGraphOptimizationLevelNone,
ORTGraphOptimizationLevelBasic,
ORTGraphOptimizationLevelExtended,
ORTGraphOptimizationLevelAll,
};
NS_ASSUME_NONNULL_END

View file

@ -3,9 +3,13 @@
#import <Foundation/Foundation.h>
#import "ort_enums.h"
NS_ASSUME_NONNULL_BEGIN
@class ORTEnv;
@class ORTRunOptions;
@class ORTSessionOptions;
@class ORTValue;
/**
@ -16,15 +20,17 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init NS_UNAVAILABLE;
/**
* Creates an ORT Session.
* Creates a session.
*
* @param env The ORT Environment instance.
* @param path The path to the ONNX model.
* @param sessionOptions Optional session configuration options.
* @param[out] error Optional error information set if an error occurs.
* @return The instance, or nil if an error occurs.
*/
- (nullable instancetype)initWithEnv:(ORTEnv*)env
modelPath:(NSString*)path
sessionOptions:(nullable ORTSessionOptions*)sessionOptions
error:(NSError**)error NS_DESIGNATED_INITIALIZER;
/**
@ -33,11 +39,13 @@ NS_ASSUME_NONNULL_BEGIN
*
* @param inputs Dictionary of input names to input ORT values.
* @param outputs Dictionary of output names to output ORT values.
* @param runOptions Optional run configuration options.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the model was run successfully.
*/
- (BOOL)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
outputs:(NSDictionary<NSString*, ORTValue*>*)outputs
runOptions:(nullable ORTRunOptions*)runOptions
error:(NSError**)error;
/**
@ -46,14 +54,151 @@ NS_ASSUME_NONNULL_BEGIN
*
* @param inputs Dictionary of input names to input ORT values.
* @param outputNames Set of output names.
* @param runOptions Optional run configuration options.
* @param[out] error Optional error information set if an error occurs.
* @return A dictionary of output names to output ORT values with the outputs
* requested in `outputNames`, or nil if an error occurs.
*/
- (nullable NSDictionary<NSString*, ORTValue*>*)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
outputNames:(NSSet<NSString*>*)outputNames
runOptions:(nullable ORTRunOptions*)runOptions
error:(NSError**)error;
@end
/**
* Options for configuring a session.
*/
@interface ORTSessionOptions : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
* Creates session configuration options.
*
* @param[out] error Optional error information set if an error occurs.
* @return The instance, or nil if an error occurs.
*/
- (nullable instancetype)initWithError:(NSError**)error NS_SWIFT_NAME(init());
/**
* Sets the number of threads used to parallelize the execution within nodes.
* A value of 0 means ORT will pick a default value.
*
* @param intraOpNumThreads The number of threads.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)setIntraOpNumThreads:(int)intraOpNumThreads
error:(NSError**)error;
/**
* Sets the graph optimization level.
*
* @param graphOptimizationLevel The graph optimization level.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)setGraphOptimizationLevel:(ORTGraphOptimizationLevel)graphOptimizationLevel
error:(NSError**)error;
/**
* Sets the path to which the optimized model file will be saved.
*
* @param optimizedModelFilePath The optimized model file path.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)setOptimizedModelFilePath:(NSString*)optimizedModelFilePath
error:(NSError**)error;
/**
* Sets the session log ID.
*
* @param logID The log ID.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)setLogID:(NSString*)logID
error:(NSError**)error;
/**
* Sets the session log severity level.
*
* @param loggingLevel The log severity level.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)setLogSeverityLevel:(ORTLoggingLevel)loggingLevel
error:(NSError**)error;
/**
* Sets a session configuration key-value pair.
* Any value for a previously set key will be overwritten.
* The session configuration keys and values are documented here:
* https://github.com/microsoft/onnxruntime/blob/master/include/onnxruntime/core/session/onnxruntime_session_options_config_keys.h
*
* @param key The key.
* @param value The value.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)addConfigEntryWithKey:(NSString*)key
value:(NSString*)value
error:(NSError**)error;
@end
/**
* Options for configuring a run.
*/
@interface ORTRunOptions : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
* Creates run configuration options.
*
* @param[out] error Optional error information set if an error occurs.
* @return The instance, or nil if an error occurs.
*/
- (nullable instancetype)initWithError:(NSError**)error NS_SWIFT_NAME(init());
/**
* Sets the run log tag.
*
* @param logTag The log tag.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)setLogTag:(NSString*)logTag
error:(NSError**)error;
/**
* Sets the run log severity level.
*
* @param loggingLevel The log severity level.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)setLogSeverityLevel:(ORTLoggingLevel)loggingLevel
error:(NSError**)error;
/**
* Sets a run configuration key-value pair.
* Any value for a previously set key will be overwritten.
* The run configuration keys and values are documented here:
* https://github.com/microsoft/onnxruntime/blob/master/include/onnxruntime/core/session/onnxruntime_run_options_config_keys.h
*
* @param key The key.
* @param value The value.
* @param[out] error Optional error information set if an error occurs.
* @return Whether the option was set successfully.
*/
- (BOOL)addConfigEntryWithKey:(NSString*)key
value:(NSString*)value
error:(NSError**)error;
@end
NS_ASSUME_NONNULL_END

View file

@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param[out] error Optional error information set if an error occurs.
* @return The instance, or nil if an error occurs.
*/
- (nullable instancetype)initTensorWithData:(NSMutableData*)tensorData
- (nullable instancetype)initWithTensorData:(NSMutableData*)tensorData
elementType:(ORTTensorElementDataType)elementType
shape:(NSArray<NSNumber*>*)shape
error:(NSError**)error;

View file

@ -3,11 +3,31 @@
#import <Foundation/Foundation.h>
#include <exception>
#include "core/session/onnxruntime_cxx_api.h"
NS_ASSUME_NONNULL_BEGIN
void ORTSaveCodeAndDescriptionToError(int code, const char* description, NSError** error);
void ORTSaveExceptionToError(const Ort::Exception& e, NSError** error);
void ORTSaveOrtExceptionToError(const Ort::Exception& e, NSError** error);
void ORTSaveExceptionToError(const std::exception& e, NSError** error);
// helper macros to catch and handle C++ exceptions
#define ORT_OBJC_API_IMPL_CATCH(error, failure_return_value) \
catch (const Ort::Exception& e) { \
ORTSaveOrtExceptionToError(e, (error)); \
return (failure_return_value); \
} \
catch (const std::exception& e) { \
ORTSaveExceptionToError(e, (error)); \
return (failure_return_value); \
}
#define ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error) \
ORT_OBJC_API_IMPL_CATCH(error, NO)
#define ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) \
ORT_OBJC_API_IMPL_CATCH(error, nil)
NS_ASSUME_NONNULL_END

View file

@ -18,8 +18,12 @@ void ORTSaveCodeAndDescriptionToError(int code, const char* descriptionCstr, NSE
userInfo:@{NSLocalizedDescriptionKey : description}];
}
void ORTSaveExceptionToError(const Ort::Exception& e, NSError** error) {
void ORTSaveOrtExceptionToError(const Ort::Exception& e, NSError** error) {
ORTSaveCodeAndDescriptionToError(e.GetOrtErrorCode(), e.what(), error);
}
void ORTSaveExceptionToError(const std::exception& e, NSError** error) {
ORTSaveCodeAndDescriptionToError(ORT_RUNTIME_EXCEPTION, e.what(), error);
}
NS_ASSUME_NONNULL_END

View file

@ -43,12 +43,28 @@ struct TensorElementTypeInfo {
};
// supported ORT tensor element data types
// define the mapping from ORTTensorElementDataType to C API
// ONNXTensorElementDataType here
// define the mapping from ORTTensorElementDataType to C API ONNXTensorElementDataType here
constexpr TensorElementTypeInfo kElementTypeInfos[]{
{ORTTensorElementDataTypeUndefined, ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED, 0},
{ORTTensorElementDataTypeFloat, ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT, sizeof(float)},
{ORTTensorElementDataTypeInt8, ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8, sizeof(int8_t)},
{ORTTensorElementDataTypeUInt8, ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8, sizeof(uint8_t)},
{ORTTensorElementDataTypeInt32, ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32, sizeof(int32_t)},
{ORTTensorElementDataTypeUInt32, ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32, sizeof(uint32_t)},
};
struct GraphOptimizationLevelInfo {
ORTGraphOptimizationLevel opt_level;
GraphOptimizationLevel capi_opt_level;
};
// ORT graph optimization levels
// define the mapping from ORTGraphOptimizationLevel to C API GraphOptimizationLevel here
constexpr GraphOptimizationLevelInfo kGraphOptimizationLevelInfos[]{
{ORTGraphOptimizationLevelNone, ORT_DISABLE_ALL},
{ORTGraphOptimizationLevelBasic, ORT_ENABLE_BASIC},
{ORTGraphOptimizationLevelExtended, ORT_ENABLE_EXTENDED},
{ORTGraphOptimizationLevelAll, ORT_ENABLE_ALL},
};
template <typename Container, typename SelectFn, typename TransformFn>
@ -59,7 +75,7 @@ auto SelectAndTransform(
const auto it = std::find_if(
std::begin(container), std::end(container), select_fn);
if (it == std::end(container)) {
throw Ort::Exception{not_found_msg, ORT_NOT_IMPLEMENTED};
ORT_CXX_API_THROW(not_found_msg, ORT_NOT_IMPLEMENTED);
}
return transform_fn(*it);
}
@ -69,12 +85,8 @@ auto SelectAndTransform(
OrtLoggingLevel PublicToCAPILoggingLevel(ORTLoggingLevel logging_level) {
return SelectAndTransform(
kLoggingLevelInfos,
[logging_level](const auto& logging_level_info) {
return logging_level_info.logging_level == logging_level;
},
[](const auto& logging_level_info) {
return logging_level_info.capi_logging_level;
},
[logging_level](const auto& logging_level_info) { return logging_level_info.logging_level == logging_level; },
[](const auto& logging_level_info) { return logging_level_info.capi_logging_level; },
"unsupported logging level");
}
@ -109,3 +121,11 @@ size_t SizeOfCAPITensorElementType(ONNXTensorElementDataType capi_type) {
[](const auto& type_info) { return type_info.element_size; },
"unsupported tensor element type");
}
GraphOptimizationLevel PublicToCAPIGraphOptimizationLevel(ORTGraphOptimizationLevel opt_level) {
return SelectAndTransform(
kGraphOptimizationLevelInfos,
[opt_level](const auto& opt_level_info) { return opt_level_info.opt_level == opt_level; },
[](const auto& opt_level_info) { return opt_level_info.capi_opt_level; },
"unsupported graph optimization level");
}

View file

@ -13,3 +13,5 @@ ONNXTensorElementDataType PublicToCAPITensorElementType(ORTTensorElementDataType
ORTTensorElementDataType CAPIToPublicTensorElementType(ONNXTensorElementDataType capi_type);
size_t SizeOfCAPITensorElementType(ONNXTensorElementDataType capi_type);
GraphOptimizationLevel PublicToCAPIGraphOptimizationLevel(ORTGraphOptimizationLevel opt_level);

View file

@ -18,17 +18,16 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable instancetype)initWithLoggingLevel:(ORTLoggingLevel)loggingLevel
error:(NSError**)error {
self = [super init];
if (self) {
try {
const auto CAPILoggingLevel = PublicToCAPILoggingLevel(loggingLevel);
_env = Ort::Env{CAPILoggingLevel};
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
self = nil;
}
if ((self = [super init]) == nil) {
return nil;
}
return self;
try {
const auto CAPILoggingLevel = PublicToCAPILoggingLevel(loggingLevel);
_env = Ort::Env{CAPILoggingLevel};
return self;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
- (Ort::Env&)CXXAPIOrtEnv {

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import "ort_session.h"
#import "ort_session_internal.h"
#include <optional>
#include <vector>
@ -9,6 +9,7 @@
#include "core/session/onnxruntime_cxx_api.h"
#import "src/error_utils.h"
#import "src/ort_enums_internal.h"
#import "src/ort_env_internal.h"
#import "src/ort_value_internal.h"
@ -20,26 +21,40 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable instancetype)initWithEnv:(ORTEnv*)env
modelPath:(NSString*)path
sessionOptions:(nullable ORTSessionOptions*)sessionOptions
error:(NSError**)error {
self = [super init];
if (self) {
try {
Ort::SessionOptions sessionOptions{}; // TODO make configurable
_session = Ort::Session{[env CXXAPIOrtEnv], path.UTF8String, sessionOptions};
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
self = nil;
}
if ((self = [super init]) == nil) {
return nil;
}
return self;
try {
if (!sessionOptions) {
sessionOptions = [[ORTSessionOptions alloc] initWithError:error];
if (!sessionOptions) {
return nil;
}
}
_session = Ort::Session{[env CXXAPIOrtEnv],
path.UTF8String,
[sessionOptions CXXAPIOrtSessionOptions]};
return self;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
- (BOOL)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
outputs:(NSDictionary<NSString*, ORTValue*>*)outputs
runOptions:(nullable ORTRunOptions*)runOptions
error:(NSError**)error {
BOOL status = NO;
try {
Ort::RunOptions runOptions{}; // TODO make configurable
if (!runOptions) {
runOptions = [[ORTRunOptions alloc] initWithError:error];
if (!runOptions) {
return NO;
}
}
std::vector<const char*> inputNames, outputNames;
std::vector<const OrtValue*> inputValues;
@ -55,24 +70,28 @@ NS_ASSUME_NONNULL_BEGIN
outputValues.push_back(static_cast<OrtValue*>([outputs[outputName] CXXAPIOrtValue]));
}
Ort::ThrowOnError(Ort::GetApi().Run(*_session, runOptions,
Ort::ThrowOnError(Ort::GetApi().Run(*_session, [runOptions CXXAPIOrtRunOptions],
inputNames.data(), inputValues.data(), inputNames.size(),
outputNames.data(), outputNames.size(), outputValues.data()));
status = YES;
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
return YES;
}
return status;
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
- (nullable NSDictionary<NSString*, ORTValue*>*)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
outputNames:(NSSet<NSString*>*)outputNameSet
runOptions:(nullable ORTRunOptions*)runOptions
error:(NSError**)error {
try {
NSArray<NSString*>* outputNameArray = outputNameSet.allObjects;
if (!runOptions) {
runOptions = [[ORTRunOptions alloc] initWithError:error];
if (!runOptions) {
return nil;
}
}
Ort::RunOptions runOptions{}; // TODO make configurable
NSArray<NSString*>* outputNameArray = outputNameSet.allObjects;
std::vector<const char*> inputNames, outputNames;
std::vector<const OrtValue*> inputValues;
@ -88,7 +107,7 @@ NS_ASSUME_NONNULL_BEGIN
outputValues.push_back(nullptr);
}
Ort::ThrowOnError(Ort::GetApi().Run(*_session, runOptions,
Ort::ThrowOnError(Ort::GetApi().Run(*_session, [runOptions CXXAPIOrtRunOptions],
inputNames.data(), inputValues.data(), inputNames.size(),
outputNames.data(), outputNames.size(), outputValues.data()));
@ -107,10 +126,144 @@ NS_ASSUME_NONNULL_BEGIN
}
return outputs;
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
@end
@implementation ORTSessionOptions {
std::optional<Ort::SessionOptions> _sessionOptions;
}
#pragma mark - Public
- (nullable instancetype)initWithError:(NSError**)error {
if ((self = [super init]) == nil) {
return nil;
}
try {
_sessionOptions = Ort::SessionOptions{};
return self;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
- (BOOL)setIntraOpNumThreads:(int)intraOpNumThreads
error:(NSError**)error {
try {
_sessionOptions->SetIntraOpNumThreads(intraOpNumThreads);
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
- (BOOL)setGraphOptimizationLevel:(ORTGraphOptimizationLevel)graphOptimizationLevel
error:(NSError**)error {
try {
_sessionOptions->SetGraphOptimizationLevel(
PublicToCAPIGraphOptimizationLevel(graphOptimizationLevel));
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
- (BOOL)setOptimizedModelFilePath:(NSString*)optimizedModelFilePath
error:(NSError**)error {
try {
_sessionOptions->SetOptimizedModelFilePath(optimizedModelFilePath.UTF8String);
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
- (BOOL)setLogID:(NSString*)logID
error:(NSError**)error {
try {
_sessionOptions->SetLogId(logID.UTF8String);
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
- (BOOL)setLogSeverityLevel:(ORTLoggingLevel)loggingLevel
error:(NSError**)error {
try {
_sessionOptions->SetLogSeverityLevel(PublicToCAPILoggingLevel(loggingLevel));
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
- (BOOL)addConfigEntryWithKey:(NSString*)key
value:(NSString*)value
error:(NSError**)error {
try {
_sessionOptions->AddConfigEntry(key.UTF8String, value.UTF8String);
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
#pragma mark - Internal
- (Ort::SessionOptions&)CXXAPIOrtSessionOptions {
return *_sessionOptions;
}
@end
@implementation ORTRunOptions {
std::optional<Ort::RunOptions> _runOptions;
}
#pragma mark - Public
- (nullable instancetype)initWithError:(NSError**)error {
if ((self = [super init]) == nil) {
return nil;
}
try {
_runOptions = Ort::RunOptions{};
return self;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
- (BOOL)setLogTag:(NSString*)logTag
error:(NSError**)error {
try {
_runOptions->SetRunTag(logTag.UTF8String);
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
- (BOOL)setLogSeverityLevel:(ORTLoggingLevel)loggingLevel
error:(NSError**)error {
try {
_runOptions->SetRunLogSeverityLevel(PublicToCAPILoggingLevel(loggingLevel));
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
- (BOOL)addConfigEntryWithKey:(NSString*)key
value:(NSString*)value
error:(NSError**)error {
try {
_runOptions->AddConfigEntry(key.UTF8String, value.UTF8String);
return YES;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error)
}
#pragma mark - Internal
- (Ort::RunOptions&)CXXAPIOrtRunOptions {
return *_runOptions;
}
@end

View file

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import "ort_session.h"
#include "core/session/onnxruntime_cxx_api.h"
NS_ASSUME_NONNULL_BEGIN
@interface ORTSessionOptions ()
- (Ort::SessionOptions&)CXXAPIOrtSessionOptions;
@end
@interface ORTRunOptions ()
- (Ort::RunOptions&)CXXAPIOrtRunOptions;
@end
NS_ASSUME_NONNULL_END

View file

@ -61,9 +61,9 @@ ORTValueTypeInfo* CXXAPIToPublicValueTypeInfo(
std::optional<Ort::TypeInfo> _typeInfo;
}
#pragma mark Public
#pragma mark - Public
- (nullable instancetype)initTensorWithData:(NSMutableData*)tensorData
- (nullable instancetype)initWithTensorData:(NSMutableData*)tensorData
elementType:(ORTTensorElementDataType)elementType
shape:(NSArray<NSNumber*>*)shape
error:(NSError**)error {
@ -82,34 +82,26 @@ ORTValueTypeInfo* CXXAPIToPublicValueTypeInfo(
memoryInfo, tensorData.mutableBytes, tensorData.length,
shapeVector.data(), shapeVector.size(), ONNXElementType);
self = [self initWithCAPIOrtValue:ortValue.release()
return [self initWithCAPIOrtValue:ortValue.release()
externalTensorData:tensorData
error:error];
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
self = nil;
}
return self;
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
- (nullable ORTValueTypeInfo*)typeInfoWithError:(NSError**)error {
try {
return CXXAPIToPublicValueTypeInfo(*_typeInfo);
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
return nil;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
- (nullable ORTTensorTypeAndShapeInfo*)tensorTypeAndShapeInfoWithError:(NSError**)error {
try {
const auto tensorTypeAndShapeInfo = _typeInfo->GetTensorTypeAndShapeInfo();
return CXXAPIToPublicTensorTypeAndShapeInfo(tensorTypeAndShapeInfo);
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
return nil;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
- (nullable NSMutableData*)tensorDataWithError:(NSError**)error {
@ -119,36 +111,35 @@ ORTValueTypeInfo* CXXAPIToPublicValueTypeInfo(
const size_t elementSize = SizeOfCAPITensorElementType(tensorTypeAndShapeInfo.GetElementType());
size_t rawDataLength;
if (!SafeMultiply(elementCount, elementSize, rawDataLength)) {
throw Ort::Exception{"failed to compute tensor data length", ORT_RUNTIME_EXCEPTION};
ORT_CXX_API_THROW("failed to compute tensor data length", ORT_RUNTIME_EXCEPTION);
}
void* rawData;
Ort::ThrowOnError(Ort::GetApi().GetTensorMutableData(*_value, &rawData));
return [NSMutableData dataWithBytesNoCopy:rawData
length:rawDataLength
freeWhenDone:NO];
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
return nil;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
#pragma mark Internal
#pragma mark - Internal
- (nullable instancetype)initWithCAPIOrtValue:(OrtValue*)CAPIOrtValue
externalTensorData:(nullable NSMutableData*)externalTensorData
error:(NSError**)error {
self = [super init];
if (self) {
try {
_value = Ort::Value{CAPIOrtValue};
_typeInfo = _value->GetTypeInfo();
_externalTensorData = externalTensorData;
} catch (const Ort::Exception& e) {
ORTSaveExceptionToError(e, error);
self = nil;
}
if ((self = [super init]) == nil) {
return nil;
}
return self;
try {
_value = Ort::Value{CAPIOrtValue};
_typeInfo = _value->GetTypeInfo();
_externalTensorData = externalTensorData;
return self;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error);
}
- (Ort::Value&)CXXAPIOrtValue {

View file

@ -56,7 +56,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (ORTValue*)ortValueWithScalarFloatData:(NSMutableData*)data {
NSArray<NSNumber*>* shape = @[ @1 ];
NSError* err = nil;
ORTValue* ortValue = [[ORTValue alloc] initTensorWithData:data
ORTValue* ortValue = [[ORTValue alloc] initWithTensorData:data
elementType:ORTTensorElementDataTypeFloat
shape:shape
error:&err];
@ -65,6 +65,22 @@ NS_ASSUME_NONNULL_BEGIN
return ortValue;
}
+ (ORTSessionOptions*)makeSessionOptions {
NSError* err = nil;
ORTSessionOptions* sessionOptions = [[ORTSessionOptions alloc] initWithError:&err];
XCTAssertNotNil(sessionOptions);
XCTAssertNil(err);
return sessionOptions;
}
+ (ORTRunOptions*)makeRunOptions {
NSError* err = nil;
ORTRunOptions* runOptions = [[ORTRunOptions alloc] initWithError:&err];
XCTAssertNotNil(runOptions);
XCTAssertNil(err);
return runOptions;
}
- (void)testInitAndRunWithPreallocatedOutputOk {
NSMutableData* aData = [ORTSessionTest dataWithScalarFloat:1.0f];
NSMutableData* bData = [ORTSessionTest dataWithScalarFloat:2.0f];
@ -77,12 +93,14 @@ NS_ASSUME_NONNULL_BEGIN
NSError* err = nil;
ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv
modelPath:[ORTSessionTest getAddModelPath]
sessionOptions:[ORTSessionTest makeSessionOptions]
error:&err];
XCTAssertNotNil(session);
XCTAssertNil(err);
BOOL runResult = [session runWithInputs:@{@"A" : a, @"B" : b}
outputs:@{@"C" : c}
runOptions:[ORTSessionTest makeRunOptions]
error:&err];
XCTAssertTrue(runResult);
XCTAssertNil(err);
@ -103,6 +121,7 @@ NS_ASSUME_NONNULL_BEGIN
NSError* err = nil;
ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv
modelPath:[ORTSessionTest getAddModelPath]
sessionOptions:[ORTSessionTest makeSessionOptions]
error:&err];
XCTAssertNotNil(session);
XCTAssertNil(err);
@ -110,6 +129,7 @@ NS_ASSUME_NONNULL_BEGIN
NSDictionary<NSString*, ORTValue*>* outputs =
[session runWithInputs:@{@"A" : a, @"B" : b}
outputNames:[NSSet setWithArray:@[ @"C" ]]
runOptions:[ORTSessionTest makeRunOptions]
error:&err];
XCTAssertNotNil(outputs);
XCTAssertNil(err);
@ -132,6 +152,7 @@ NS_ASSUME_NONNULL_BEGIN
NSError* err = nil;
ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv
modelPath:invalidModelPath
sessionOptions:[ORTSessionTest makeSessionOptions]
error:&err];
XCTAssertNil(session);
XCTAssertNotNil(err);
@ -147,12 +168,14 @@ NS_ASSUME_NONNULL_BEGIN
NSError* err = nil;
ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv
modelPath:[ORTSessionTest getAddModelPath]
sessionOptions:[ORTSessionTest makeSessionOptions]
error:&err];
XCTAssertNotNil(session);
XCTAssertNil(err);
BOOL runResult = [session runWithInputs:@{@"D" : d}
outputs:@{@"C" : c}
runOptions:[ORTSessionTest makeRunOptions]
error:&err];
XCTAssertFalse(runResult);
XCTAssertNotNil(err);

View file

@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
const ORTTensorElementDataType elementType = ORTTensorElementDataTypeInt32;
NSError* err = nil;
ORTValue* ortValue = [[ORTValue alloc] initTensorWithData:data
ORTValue* ortValue = [[ORTValue alloc] initWithTensorData:data
elementType:elementType
shape:shape
error:&err];
@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
NSArray<NSNumber*>* shape = @[ @2, @3 ]; // too large
NSError* err = nil;
ORTValue* ortValue = [[ORTValue alloc] initTensorWithData:data
ORTValue* ortValue = [[ORTValue alloc] initWithTensorData:data
elementType:ORTTensorElementDataTypeInt32
shape:shape
error:&err];