diff --git a/Package.swift b/Package.swift index 167051f..6d09521 100644 --- a/Package.swift +++ b/Package.swift @@ -31,7 +31,7 @@ let package = Package( .target(name: "OnnxRuntimeBindings", dependencies: ["onnxruntime"], path: "objectivec", - exclude: ["test", "docs", "ReadMe.md", "format_objc.sh"], + exclude: ["ReadMe.md", "format_objc.sh"], cxxSettings: [ .define("SPM_BUILD"), .unsafeFlags(["-std=c++17", diff --git a/objectivec/assert_arc_enabled.mm b/objectivec/assert_arc_enabled.mm deleted file mode 100644 index 9aa0bad..0000000 --- a/objectivec/assert_arc_enabled.mm +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -static_assert(__has_feature(objc_arc), "Objective-C ARC must be enabled."); diff --git a/objectivec/docs/jazzy_config.yaml b/objectivec/docs/jazzy_config.yaml deleted file mode 100644 index 676f89d..0000000 --- a/objectivec/docs/jazzy_config.yaml +++ /dev/null @@ -1,13 +0,0 @@ -module: ONNX Runtime Objective-C API -author: ONNX Runtime Authors -author_url: https://www.onnxruntime.ai -github_url: https://github.com/microsoft/onnxruntime - -objc: true -umbrella_header: ../include/onnxruntime.h -framework_root: .. - -readme: ./main_page.md - -hide_documentation_coverage: true -undocumented_text: "" diff --git a/objectivec/docs/main_page.md b/objectivec/docs/main_page.md deleted file mode 100644 index fdc7c80..0000000 --- a/objectivec/docs/main_page.md +++ /dev/null @@ -1,5 +0,0 @@ -# ONNX Runtime Objective-C API - -ONNX Runtime provides an Objective-C API. - -It can be used from Objective-C/C++ or Swift with a bridging header. diff --git a/objectivec/docs/readme.md b/objectivec/docs/readme.md deleted file mode 100644 index 5697480..0000000 --- a/objectivec/docs/readme.md +++ /dev/null @@ -1,17 +0,0 @@ -# Objective-C API Documentation - -The API should be documented with comments in the [public header files](../include). - -## Documentation Generation - -The [Jazzy](https://github.com/realm/jazzy) tool is used to generate documentation from the code. - -To generate documentation, from the repo root, run: - -```bash -jazzy --config objectivec/docs/jazzy_config.yaml --output -``` - -The generated documentation website files will be in ``. - -[main_page.md](./main_page.md) contains content for the main page of the generated documentation website. diff --git a/objectivec/error_utils.mm b/objectivec/error_utils.mm deleted file mode 100644 index 9186326..0000000 --- a/objectivec/error_utils.mm +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import "error_utils.h" - -NS_ASSUME_NONNULL_BEGIN - -static NSString* const kOrtErrorDomain = @"onnxruntime"; - -void ORTSaveCodeAndDescriptionToError(int code, const char* descriptionCstr, NSError** error) { - if (!error) return; - - NSString* description = [NSString stringWithCString:descriptionCstr - encoding:NSASCIIStringEncoding]; - - *error = [NSError errorWithDomain:kOrtErrorDomain - code:code - userInfo:@{NSLocalizedDescriptionKey : description}]; -} - -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 diff --git a/objectivec/ort_coreml_execution_provider.mm b/objectivec/ort_coreml_execution_provider.mm deleted file mode 100644 index 6340fde..0000000 --- a/objectivec/ort_coreml_execution_provider.mm +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import "ort_coreml_execution_provider.h" - -#import "cxx_api.h" -#import "error_utils.h" -#import "ort_session_internal.h" - -NS_ASSUME_NONNULL_BEGIN - -BOOL ORTIsCoreMLExecutionProviderAvailable() { - return ORT_OBJC_API_COREML_EP_AVAILABLE ? YES : NO; -} - -@implementation ORTCoreMLExecutionProviderOptions - -@end - -@implementation ORTSessionOptions (ORTSessionOptionsCoreMLEP) - -- (BOOL)appendCoreMLExecutionProviderWithOptions:(ORTCoreMLExecutionProviderOptions*)options - error:(NSError**)error { -#if ORT_OBJC_API_COREML_EP_AVAILABLE - try { - const uint32_t flags = - (options.useCPUOnly ? COREML_FLAG_USE_CPU_ONLY : 0) | - (options.enableOnSubgraphs ? COREML_FLAG_ENABLE_ON_SUBGRAPH : 0) | - (options.onlyEnableForDevicesWithANE ? COREML_FLAG_ONLY_ENABLE_DEVICE_WITH_ANE : 0); - Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_CoreML( - [self CXXAPIOrtSessionOptions], flags)); - return YES; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error); -#else // !ORT_OBJC_API_COREML_EP_AVAILABLE - static_cast(options); - ORTSaveCodeAndDescriptionToError(ORT_FAIL, "CoreML execution provider is not enabled.", error); - return NO; -#endif -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/objectivec/ort_enums.mm b/objectivec/ort_enums.mm deleted file mode 100644 index 0144a33..0000000 --- a/objectivec/ort_enums.mm +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import "ort_enums_internal.h" - -#include - -#import "cxx_api.h" - -namespace { - -struct LoggingLevelInfo { - ORTLoggingLevel logging_level; - OrtLoggingLevel capi_logging_level; -}; - -// supported ORT logging levels -// define the mapping from ORTLoggingLevel to C API OrtLoggingLevel here -constexpr LoggingLevelInfo kLoggingLevelInfos[]{ - {ORTLoggingLevelVerbose, ORT_LOGGING_LEVEL_VERBOSE}, - {ORTLoggingLevelInfo, ORT_LOGGING_LEVEL_INFO}, - {ORTLoggingLevelWarning, ORT_LOGGING_LEVEL_WARNING}, - {ORTLoggingLevelError, ORT_LOGGING_LEVEL_ERROR}, - {ORTLoggingLevelFatal, ORT_LOGGING_LEVEL_FATAL}, -}; - -struct ValueTypeInfo { - ORTValueType type; - ONNXType capi_type; -}; - -// supported ORT value types -// define the mapping from ORTValueType to C API ONNXType here -constexpr ValueTypeInfo kValueTypeInfos[]{ - {ORTValueTypeUnknown, ONNX_TYPE_UNKNOWN}, - {ORTValueTypeTensor, ONNX_TYPE_TENSOR}, -}; - -struct TensorElementTypeInfo { - ORTTensorElementDataType type; - ONNXTensorElementDataType capi_type; - size_t element_size; -}; - -// supported ORT tensor element data types -// 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)}, - {ORTTensorElementDataTypeInt64, ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64, sizeof(int64_t)}, - {ORTTensorElementDataTypeUInt64, ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64, sizeof(uint64_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 -auto SelectAndTransform( - const Container& container, SelectFn select_fn, TransformFn transform_fn, - const char* not_found_msg) - -> decltype(transform_fn(*std::begin(container))) { - const auto it = std::find_if( - std::begin(container), std::end(container), select_fn); - if (it == std::end(container)) { - ORT_CXX_API_THROW(not_found_msg, ORT_NOT_IMPLEMENTED); - } - return transform_fn(*it); -} - -} // namespace - -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; }, - "unsupported logging level"); -} - -ORTValueType CAPIToPublicValueType(ONNXType capi_type) { - return SelectAndTransform( - kValueTypeInfos, - [capi_type](const auto& type_info) { return type_info.capi_type == capi_type; }, - [](const auto& type_info) { return type_info.type; }, - "unsupported value type"); -} - -ONNXTensorElementDataType PublicToCAPITensorElementType(ORTTensorElementDataType type) { - return SelectAndTransform( - kElementTypeInfos, - [type](const auto& type_info) { return type_info.type == type; }, - [](const auto& type_info) { return type_info.capi_type; }, - "unsupported tensor element type"); -} - -ORTTensorElementDataType CAPIToPublicTensorElementType(ONNXTensorElementDataType capi_type) { - return SelectAndTransform( - kElementTypeInfos, - [capi_type](const auto& type_info) { return type_info.capi_type == capi_type; }, - [](const auto& type_info) { return type_info.type; }, - "unsupported tensor element type"); -} - -size_t SizeOfCAPITensorElementType(ONNXTensorElementDataType capi_type) { - return SelectAndTransform( - kElementTypeInfos, - [capi_type](const auto& type_info) { return type_info.capi_type == 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"); -} diff --git a/objectivec/ort_env.mm b/objectivec/ort_env.mm deleted file mode 100644 index cd83ac5..0000000 --- a/objectivec/ort_env.mm +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import "ort_env_internal.h" - -#include - -#import "cxx_api.h" - -#import "error_utils.h" -#import "ort_enums_internal.h" - -NS_ASSUME_NONNULL_BEGIN - -NSString* ORTVersion(void) { - std::string result = OrtGetApiBase()->GetVersionString(); - return [NSString stringWithUTF8String:result.c_str()]; -} - -@implementation ORTEnv { - std::optional _env; -} - -- (nullable instancetype)initWithLoggingLevel:(ORTLoggingLevel)loggingLevel - error:(NSError**)error { - if ((self = [super init]) == nil) { - return nil; - } - - try { - const auto CAPILoggingLevel = PublicToCAPILoggingLevel(loggingLevel); - _env = Ort::Env{CAPILoggingLevel}; - return self; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) -} - -- (Ort::Env&)CXXAPIOrtEnv { - return *_env; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/objectivec/ort_session.mm b/objectivec/ort_session.mm deleted file mode 100644 index c4f57b0..0000000 --- a/objectivec/ort_session.mm +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import "ort_session_internal.h" - -#include -#include - -#import "cxx_api.h" -#import "error_utils.h" -#import "ort_enums_internal.h" -#import "ort_env_internal.h" -#import "ort_value_internal.h" - -namespace { -enum class NamedValueType { - Input, - OverridableInitializer, - Output, -}; -} // namespace - -NS_ASSUME_NONNULL_BEGIN - -@implementation ORTSession { - std::optional _session; -} - -#pragma mark - Public - -- (nullable instancetype)initWithEnv:(ORTEnv*)env - modelPath:(NSString*)path - sessionOptions:(nullable ORTSessionOptions*)sessionOptions - error:(NSError**)error { - if ((self = [super init]) == nil) { - return nil; - } - - 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*)inputs - outputs:(NSDictionary*)outputs - runOptions:(nullable ORTRunOptions*)runOptions - error:(NSError**)error { - try { - if (!runOptions) { - runOptions = [[ORTRunOptions alloc] initWithError:error]; - if (!runOptions) { - return NO; - } - } - - std::vector inputNames, outputNames; - std::vector inputValues; - std::vector outputValues; - - for (NSString* inputName in inputs) { - inputNames.push_back(inputName.UTF8String); - inputValues.push_back(static_cast([inputs[inputName] CXXAPIOrtValue])); - } - - for (NSString* outputName in outputs) { - outputNames.push_back(outputName.UTF8String); - outputValues.push_back(static_cast([outputs[outputName] CXXAPIOrtValue])); - } - - Ort::ThrowOnError(Ort::GetApi().Run(*_session, [runOptions CXXAPIOrtRunOptions], - inputNames.data(), inputValues.data(), inputNames.size(), - outputNames.data(), outputNames.size(), outputValues.data())); - - return YES; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error) -} - -- (nullable NSDictionary*)runWithInputs:(NSDictionary*)inputs - outputNames:(NSSet*)outputNameSet - runOptions:(nullable ORTRunOptions*)runOptions - error:(NSError**)error { - try { - if (!runOptions) { - runOptions = [[ORTRunOptions alloc] initWithError:error]; - if (!runOptions) { - return nil; - } - } - - NSArray* outputNameArray = outputNameSet.allObjects; - - std::vector inputNames, outputNames; - std::vector inputValues; - std::vector outputValues; - - for (NSString* inputName in inputs) { - inputNames.push_back(inputName.UTF8String); - inputValues.push_back(static_cast([inputs[inputName] CXXAPIOrtValue])); - } - - for (NSString* outputName in outputNameArray) { - outputNames.push_back(outputName.UTF8String); - outputValues.push_back(nullptr); - } - - Ort::ThrowOnError(Ort::GetApi().Run(*_session, [runOptions CXXAPIOrtRunOptions], - inputNames.data(), inputValues.data(), inputNames.size(), - outputNames.data(), outputNames.size(), outputValues.data())); - - NSMutableDictionary* outputs = [[NSMutableDictionary alloc] init]; - for (NSUInteger i = 0; i < outputNameArray.count; ++i) { - ORTValue* outputValue = [[ORTValue alloc] initWithCAPIOrtValue:outputValues[i] externalTensorData:nil error:error]; - if (!outputValue) { - // clean up remaining C API OrtValues which haven't been wrapped by an ORTValue yet - for (NSUInteger j = i; j < outputNameArray.count; ++j) { - Ort::GetApi().ReleaseValue(outputValues[j]); - } - return nil; - } - - outputs[outputNameArray[i]] = outputValue; - } - - return outputs; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) -} - -- (nullable NSArray*)inputNamesWithError:(NSError**)error { - return [self namesWithType:NamedValueType::Input error:error]; -} - -- (nullable NSArray*)overridableInitializerNamesWithError:(NSError**)error { - return [self namesWithType:NamedValueType::OverridableInitializer error:error]; -} - -- (nullable NSArray*)outputNamesWithError:(NSError**)error { - return [self namesWithType:NamedValueType::Output error:error]; -} - -#pragma mark - Private - -- (nullable NSArray*)namesWithType:(NamedValueType)namedValueType - error:(NSError**)error { - try { - auto getCount = [&session = *_session, namedValueType]() { - if (namedValueType == NamedValueType::Input) { - return session.GetInputCount(); - } else if (namedValueType == NamedValueType::OverridableInitializer) { - return session.GetOverridableInitializerCount(); - } else { - return session.GetOutputCount(); - } - }; - - auto getName = [&session = *_session, namedValueType](size_t i, OrtAllocator* allocator) { - if (namedValueType == NamedValueType::Input) { - return session.GetInputNameAllocated(i, allocator); - } else if (namedValueType == NamedValueType::OverridableInitializer) { - return session.GetOverridableInitializerNameAllocated(i, allocator); - } else { - return session.GetOutputNameAllocated(i, allocator); - } - }; - - const size_t nameCount = getCount(); - - Ort::AllocatorWithDefaultOptions allocator; - NSMutableArray* result = [NSMutableArray arrayWithCapacity:nameCount]; - - for (size_t i = 0; i < nameCount; ++i) { - auto name = getName(i, allocator); - NSString* nameNsstr = [NSString stringWithUTF8String:name.get()]; - NSAssert(nameNsstr != nil, @"nameNsstr must not be nil"); - [result addObject:nameNsstr]; - } - - return result; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) -} - -@end - -@implementation ORTSessionOptions { - std::optional _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)appendExecutionProvider:(NSString*)providerName - providerOptions:(NSDictionary*)providerOptions - error:(NSError**)error { - try { - std::unordered_map options; - NSArray* keys = [providerOptions allKeys]; - - for (NSString* key in keys) { - NSString* value = [providerOptions objectForKey:key]; - options.emplace(key.UTF8String, value.UTF8String); - } - - _sessionOptions->AppendExecutionProvider(providerName.UTF8String, options); - return YES; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(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) -} - -- (BOOL)registerCustomOpsUsingFunction:(NSString*)registrationFuncName - error:(NSError**)error { - try { - _sessionOptions->RegisterCustomOpsUsingFunction(registrationFuncName.UTF8String); - return YES; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error) -} - -#pragma mark - Internal - -- (Ort::SessionOptions&)CXXAPIOrtSessionOptions { - return *_sessionOptions; -} - -@end - -@implementation ORTRunOptions { - std::optional _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 - -NS_ASSUME_NONNULL_END diff --git a/objectivec/ort_value.mm b/objectivec/ort_value.mm deleted file mode 100644 index ce77ca7..0000000 --- a/objectivec/ort_value.mm +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import "ort_value_internal.h" - -#include - -#import "cxx_api.h" -#import "error_utils.h" -#import "ort_enums_internal.h" - -NS_ASSUME_NONNULL_BEGIN - -namespace { - -ORTTensorTypeAndShapeInfo* CXXAPIToPublicTensorTypeAndShapeInfo( - const Ort::ConstTensorTypeAndShapeInfo& CXXAPITensorTypeAndShapeInfo) { - auto* result = [[ORTTensorTypeAndShapeInfo alloc] init]; - const auto elementType = CXXAPITensorTypeAndShapeInfo.GetElementType(); - const std::vector shape = CXXAPITensorTypeAndShapeInfo.GetShape(); - - result.elementType = CAPIToPublicTensorElementType(elementType); - auto* shapeArray = [[NSMutableArray alloc] initWithCapacity:shape.size()]; - for (size_t i = 0; i < shape.size(); ++i) { - shapeArray[i] = @(shape[i]); - } - result.shape = shapeArray; - - return result; -} - -ORTValueTypeInfo* CXXAPIToPublicValueTypeInfo( - const Ort::TypeInfo& CXXAPITypeInfo) { - auto* result = [[ORTValueTypeInfo alloc] init]; - const auto valueType = CXXAPITypeInfo.GetONNXType(); - - result.type = CAPIToPublicValueType(valueType); - - if (valueType == ONNX_TYPE_TENSOR) { - const auto tensorTypeAndShapeInfo = CXXAPITypeInfo.GetTensorTypeAndShapeInfo(); - result.tensorTypeAndShapeInfo = CXXAPIToPublicTensorTypeAndShapeInfo(tensorTypeAndShapeInfo); - } - - return result; -} - -// out = a * b -// returns true iff the result does not overflow -bool SafeMultiply(size_t a, size_t b, size_t& out) { - return !__builtin_mul_overflow(a, b, &out); -} - -} // namespace - -@interface ORTValue () - -// pointer to any external tensor data to keep alive for the lifetime of the ORTValue -@property(nonatomic, nullable) NSMutableData* externalTensorData; - -@end - -@implementation ORTValue { - std::optional _value; - std::optional _typeInfo; -} - -#pragma mark - Public - -- (nullable instancetype)initWithTensorData:(NSMutableData*)tensorData - elementType:(ORTTensorElementDataType)elementType - shape:(NSArray*)shape - error:(NSError**)error { - try { - const auto memoryInfo = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU); - const auto ONNXElementType = PublicToCAPITensorElementType(elementType); - const auto shapeVector = [shape]() { - std::vector result{}; - result.reserve(shape.count); - for (NSNumber* dim in shape) { - result.push_back(dim.longLongValue); - } - return result; - }(); - Ort::Value ortValue = Ort::Value::CreateTensor( - memoryInfo, tensorData.mutableBytes, tensorData.length, - shapeVector.data(), shapeVector.size(), ONNXElementType); - - return [self initWithCAPIOrtValue:ortValue.release() - externalTensorData:tensorData - error:error]; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) -} - -- (nullable ORTValueTypeInfo*)typeInfoWithError:(NSError**)error { - try { - return CXXAPIToPublicValueTypeInfo(*_typeInfo); - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) -} - -- (nullable ORTTensorTypeAndShapeInfo*)tensorTypeAndShapeInfoWithError:(NSError**)error { - try { - const auto tensorTypeAndShapeInfo = _typeInfo->GetTensorTypeAndShapeInfo(); - return CXXAPIToPublicTensorTypeAndShapeInfo(tensorTypeAndShapeInfo); - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) -} - -- (nullable NSMutableData*)tensorDataWithError:(NSError**)error { - try { - const auto tensorTypeAndShapeInfo = _typeInfo->GetTensorTypeAndShapeInfo(); - const size_t elementCount = tensorTypeAndShapeInfo.GetElementCount(); - const size_t elementSize = SizeOfCAPITensorElementType(tensorTypeAndShapeInfo.GetElementType()); - size_t rawDataLength; - if (!SafeMultiply(elementCount, elementSize, rawDataLength)) { - 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]; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error) -} - -#pragma mark - Internal - -- (nullable instancetype)initWithCAPIOrtValue:(OrtValue*)CAPIOrtValue - externalTensorData:(nullable NSMutableData*)externalTensorData - error:(NSError**)error { - if ((self = [super init]) == nil) { - return nil; - } - - try { - _value = Ort::Value{CAPIOrtValue}; - _typeInfo = _value->GetTypeInfo(); - _externalTensorData = externalTensorData; - return self; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error); -} - -- (Ort::Value&)CXXAPIOrtValue { - return *_value; -} - -@end - -@implementation ORTValueTypeInfo -@end - -@implementation ORTTensorTypeAndShapeInfo -@end - -NS_ASSUME_NONNULL_END diff --git a/objectivec/ort_xnnpack_execution_provider.mm b/objectivec/ort_xnnpack_execution_provider.mm deleted file mode 100644 index 324974a..0000000 --- a/objectivec/ort_xnnpack_execution_provider.mm +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import "ort_xnnpack_execution_provider.h" - -#import "cxx_api.h" -#import "error_utils.h" -#import "ort_session_internal.h" - -NS_ASSUME_NONNULL_BEGIN - -@implementation ORTXnnpackExecutionProviderOptions - -@end - -@implementation ORTSessionOptions (ORTSessionOptionsXnnpackEP) - -- (BOOL)appendXnnpackExecutionProviderWithOptions:(ORTXnnpackExecutionProviderOptions*)options - error:(NSError**)error { - try { - NSDictionary* provider_options = @{ - @"intra_op_num_threads" : [NSString stringWithFormat:@"%d", options.intra_op_num_threads] - }; - return [self appendExecutionProvider:@"XNNPACK" providerOptions:provider_options error:error]; - } - ORT_OBJC_API_IMPL_CATCH_RETURNING_BOOL(error); -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/objectivec/test/assert_arc_enabled.mm b/objectivec/test/assert_arc_enabled.mm deleted file mode 100644 index 9aa0bad..0000000 --- a/objectivec/test/assert_arc_enabled.mm +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -static_assert(__has_feature(objc_arc), "Objective-C ARC must be enabled."); diff --git a/objectivec/test/assertion_utils.h b/objectivec/test/assertion_utils.h deleted file mode 100644 index f2b73e6..0000000 --- a/objectivec/test/assertion_utils.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import - -NS_ASSUME_NONNULL_BEGIN - -#define ORTAssertNullableResultSuccessful(result, error) \ - do { \ - XCTAssertNotNil(result, @"Expected non-nil result but got nil. Error: %@", error); \ - XCTAssertNil(error); \ - } while (0) - -#define ORTAssertBoolResultSuccessful(result, error) \ - do { \ - XCTAssertTrue(result, @"Expected true result but got false. Error: %@", error); \ - XCTAssertNil(error); \ - } while (0) - -#define ORTAssertNullableResultUnsuccessful(result, error) \ - do { \ - XCTAssertNil(result); \ - XCTAssertNotNil(error); \ - } while (0) - -#define ORTAssertBoolResultUnsuccessful(result, error) \ - do { \ - XCTAssertFalse(result); \ - XCTAssertNotNil(error); \ - } while (0) - -NS_ASSUME_NONNULL_END diff --git a/objectivec/test/ort_env_test.mm b/objectivec/test/ort_env_test.mm deleted file mode 100644 index 420f55f..0000000 --- a/objectivec/test/ort_env_test.mm +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import - -#import "ort_env.h" - -#import "test/assertion_utils.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface ORTEnvTest : XCTestCase -@end - -@implementation ORTEnvTest -- (void)testGetOrtVersion { - NSString* ver = ORTVersion(); - XCTAssertNotNil(ver); -} - -- (void)testInitOk { - NSError* err = nil; - ORTEnv* env = [[ORTEnv alloc] initWithLoggingLevel:ORTLoggingLevelWarning - error:&err]; - ORTAssertNullableResultSuccessful(env, err); -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/objectivec/test/ort_session_test.mm b/objectivec/test/ort_session_test.mm deleted file mode 100644 index 790ad1c..0000000 --- a/objectivec/test/ort_session_test.mm +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import - -#import "ort_coreml_execution_provider.h" -#import "ort_xnnpack_execution_provider.h" -#import "ort_env.h" -#import "ort_session.h" -#import "ort_value.h" - -#import "test/assertion_utils.h" - -#include - -NS_ASSUME_NONNULL_BEGIN - -@interface ORTSessionTest : XCTestCase - -@property(readonly, nullable) ORTEnv* ortEnv; - -@end - -@implementation ORTSessionTest - -- (void)setUp { - [super setUp]; - - self.continueAfterFailure = NO; - - NSError* err = nil; - _ortEnv = [[ORTEnv alloc] initWithLoggingLevel:ORTLoggingLevelWarning - error:&err]; - ORTAssertNullableResultSuccessful(_ortEnv, err); -} - -- (void)tearDown { - _ortEnv = nil; - - [super tearDown]; -} - -// model with an Add op -// inputs: A, B -// output: C = A + B -+ (NSString*)getAddModelPath { - NSBundle* bundle = [NSBundle bundleForClass:[ORTSessionTest class]]; - NSString* path = [bundle pathForResource:@"single_add.basic" - ofType:@"ort"]; - return path; -} - -+ (NSMutableData*)dataWithScalarFloat:(float)value { - NSMutableData* data = [[NSMutableData alloc] initWithBytes:&value length:sizeof(value)]; - return data; -} - -+ (ORTValue*)ortValueWithScalarFloatData:(NSMutableData*)data { - NSArray* shape = @[ @1 ]; - NSError* err = nil; - ORTValue* ortValue = [[ORTValue alloc] initWithTensorData:data - elementType:ORTTensorElementDataTypeFloat - shape:shape - error:&err]; - ORTAssertNullableResultSuccessful(ortValue, err); - return ortValue; -} - -+ (ORTSessionOptions*)makeSessionOptions { - NSError* err = nil; - ORTSessionOptions* sessionOptions = [[ORTSessionOptions alloc] initWithError:&err]; - ORTAssertNullableResultSuccessful(sessionOptions, err); - return sessionOptions; -} - -+ (ORTRunOptions*)makeRunOptions { - NSError* err = nil; - ORTRunOptions* runOptions = [[ORTRunOptions alloc] initWithError:&err]; - ORTAssertNullableResultSuccessful(runOptions, err); - return runOptions; -} - -- (void)testInitAndRunWithPreallocatedOutputOk { - NSMutableData* aData = [ORTSessionTest dataWithScalarFloat:1.0f]; - NSMutableData* bData = [ORTSessionTest dataWithScalarFloat:2.0f]; - NSMutableData* cData = [ORTSessionTest dataWithScalarFloat:0.0f]; - - ORTValue* a = [ORTSessionTest ortValueWithScalarFloatData:aData]; - ORTValue* b = [ORTSessionTest ortValueWithScalarFloatData:bData]; - ORTValue* c = [ORTSessionTest ortValueWithScalarFloatData:cData]; - - NSError* err = nil; - ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv - modelPath:[ORTSessionTest getAddModelPath] - sessionOptions:[ORTSessionTest makeSessionOptions] - error:&err]; - ORTAssertNullableResultSuccessful(session, err); - - BOOL runResult = [session runWithInputs:@{@"A" : a, @"B" : b} - outputs:@{@"C" : c} - runOptions:[ORTSessionTest makeRunOptions] - error:&err]; - ORTAssertBoolResultSuccessful(runResult, err); - - const float cExpected = 3.0f; - float cActual; - memcpy(&cActual, cData.bytes, sizeof(float)); - XCTAssertEqual(cActual, cExpected); -} - -- (void)testInitAndRunOk { - NSMutableData* aData = [ORTSessionTest dataWithScalarFloat:1.0f]; - NSMutableData* bData = [ORTSessionTest dataWithScalarFloat:2.0f]; - - ORTValue* a = [ORTSessionTest ortValueWithScalarFloatData:aData]; - ORTValue* b = [ORTSessionTest ortValueWithScalarFloatData:bData]; - - NSError* err = nil; - ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv - modelPath:[ORTSessionTest getAddModelPath] - sessionOptions:[ORTSessionTest makeSessionOptions] - error:&err]; - ORTAssertNullableResultSuccessful(session, err); - - NSDictionary* outputs = - [session runWithInputs:@{@"A" : a, @"B" : b} - outputNames:[NSSet setWithArray:@[ @"C" ]] - runOptions:[ORTSessionTest makeRunOptions] - error:&err]; - ORTAssertNullableResultSuccessful(outputs, err); - - ORTValue* cOutput = outputs[@"C"]; - XCTAssertNotNil(cOutput); - - NSData* cData = [cOutput tensorDataWithError:&err]; - ORTAssertNullableResultSuccessful(cData, err); - - const float cExpected = 3.0f; - float cActual; - memcpy(&cActual, cData.bytes, sizeof(float)); - XCTAssertEqual(cActual, cExpected); -} - -- (void)testGetNamesOk { - NSError* err = nil; - ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv - modelPath:[ORTSessionTest getAddModelPath] - sessionOptions:[ORTSessionTest makeSessionOptions] - error:&err]; - ORTAssertNullableResultSuccessful(session, err); - - NSArray* inputNames = [session inputNamesWithError:&err]; - ORTAssertNullableResultSuccessful(inputNames, err); - XCTAssertEqualObjects(inputNames, (@[ @"A", @"B" ])); - - NSArray* overridableInitializerNames = [session overridableInitializerNamesWithError:&err]; - ORTAssertNullableResultSuccessful(overridableInitializerNames, err); - XCTAssertEqualObjects(overridableInitializerNames, (@[])); - - NSArray* outputNames = [session outputNamesWithError:&err]; - ORTAssertNullableResultSuccessful(outputNames, err); - XCTAssertEqualObjects(outputNames, (@[ @"C" ])); -} - -- (void)testInitFailsWithInvalidPath { - NSString* invalidModelPath = @"invalid/path/to/model.ort"; - NSError* err = nil; - ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv - modelPath:invalidModelPath - sessionOptions:[ORTSessionTest makeSessionOptions] - error:&err]; - ORTAssertNullableResultUnsuccessful(session, err); -} - -- (void)testRunFailsWithInvalidInput { - NSMutableData* dData = [ORTSessionTest dataWithScalarFloat:1.0f]; - NSMutableData* cData = [ORTSessionTest dataWithScalarFloat:0.0f]; - - ORTValue* d = [ORTSessionTest ortValueWithScalarFloatData:dData]; - ORTValue* c = [ORTSessionTest ortValueWithScalarFloatData:cData]; - - NSError* err = nil; - ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv - modelPath:[ORTSessionTest getAddModelPath] - sessionOptions:[ORTSessionTest makeSessionOptions] - error:&err]; - ORTAssertNullableResultSuccessful(session, err); - - BOOL runResult = [session runWithInputs:@{@"D" : d} - outputs:@{@"C" : c} - runOptions:[ORTSessionTest makeRunOptions] - error:&err]; - ORTAssertBoolResultUnsuccessful(runResult, err); -} - -- (void)testAppendCoreMLEP { - NSError* err = nil; - ORTSessionOptions* sessionOptions = [ORTSessionTest makeSessionOptions]; - ORTCoreMLExecutionProviderOptions* coreMLOptions = [[ORTCoreMLExecutionProviderOptions alloc] init]; - coreMLOptions.enableOnSubgraphs = YES; // set an arbitrary option - - BOOL appendResult = [sessionOptions appendCoreMLExecutionProviderWithOptions:coreMLOptions - error:&err]; - - if (!ORTIsCoreMLExecutionProviderAvailable()) { - ORTAssertBoolResultUnsuccessful(appendResult, err); - return; - } - - ORTAssertBoolResultSuccessful(appendResult, err); - - ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv - modelPath:[ORTSessionTest getAddModelPath] - sessionOptions:sessionOptions - error:&err]; - ORTAssertNullableResultSuccessful(session, err); -} - -- (void)testAppendXnnpackEP { - NSError* err = nil; - ORTSessionOptions* sessionOptions = [ORTSessionTest makeSessionOptions]; - ORTXnnpackExecutionProviderOptions* XnnpackOptions = [[ORTXnnpackExecutionProviderOptions alloc] init]; - XnnpackOptions.intra_op_num_threads = 2; - - BOOL appendResult = [sessionOptions appendXnnpackExecutionProviderWithOptions:XnnpackOptions - error:&err]; - // Without xnnpack EP in building also can pass the test - NSString* err_msg = [err localizedDescription]; - if (!appendResult && [err_msg containsString:@"XNNPACK execution provider is not supported in this build. "]) { - return; - } - - ORTAssertBoolResultSuccessful(appendResult, err); - - ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv - modelPath:[ORTSessionTest getAddModelPath] - sessionOptions:sessionOptions - error:&err]; - ORTAssertNullableResultSuccessful(session, err); -} -@end - -NS_ASSUME_NONNULL_END diff --git a/objectivec/test/ort_value_test.mm b/objectivec/test/ort_value_test.mm deleted file mode 100644 index 734ad39..0000000 --- a/objectivec/test/ort_value_test.mm +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#import - -#import "ort_value.h" - -#include - -#import "test/assertion_utils.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface ORTValueTest : XCTestCase -@end - -@implementation ORTValueTest - -- (void)setUp { - [super setUp]; - - self.continueAfterFailure = NO; -} - -- (void)testInitTensorOk { - int32_t value = 42; - NSMutableData* data = [[NSMutableData alloc] initWithBytes:&value - length:sizeof(int32_t)]; - NSArray* shape = @[ @1 ]; - - const ORTTensorElementDataType elementType = ORTTensorElementDataTypeInt32; - - NSError* err = nil; - ORTValue* ortValue = [[ORTValue alloc] initWithTensorData:data - elementType:elementType - shape:shape - error:&err]; - ORTAssertNullableResultSuccessful(ortValue, err); - - auto checkTensorInfo = [&](ORTTensorTypeAndShapeInfo* tensorInfo) { - XCTAssertEqual(tensorInfo.elementType, elementType); - XCTAssertEqualObjects(tensorInfo.shape, shape); - }; - - ORTValueTypeInfo* typeInfo = [ortValue typeInfoWithError:&err]; - ORTAssertNullableResultSuccessful(typeInfo, err); - XCTAssertEqual(typeInfo.type, ORTValueTypeTensor); - XCTAssertNotNil(typeInfo.tensorTypeAndShapeInfo); - checkTensorInfo(typeInfo.tensorTypeAndShapeInfo); - - ORTTensorTypeAndShapeInfo* tensorInfo = [ortValue tensorTypeAndShapeInfoWithError:&err]; - ORTAssertNullableResultSuccessful(tensorInfo, err); - checkTensorInfo(tensorInfo); - - NSData* actualData = [ortValue tensorDataWithError:&err]; - ORTAssertNullableResultSuccessful(actualData, err); - XCTAssertEqual(actualData.length, sizeof(int32_t)); - int32_t actualValue; - memcpy(&actualValue, actualData.bytes, sizeof(int32_t)); - XCTAssertEqual(actualValue, value); -} - -- (void)testInitTensorFailsWithDataSmallerThanShape { - std::vector values{1, 2, 3, 4}; - NSMutableData* data = [[NSMutableData alloc] initWithBytes:values.data() - length:values.size() * sizeof(int32_t)]; - NSArray* shape = @[ @2, @3 ]; // too large - - NSError* err = nil; - ORTValue* ortValue = [[ORTValue alloc] initWithTensorData:data - elementType:ORTTensorElementDataTypeInt32 - shape:shape - error:&err]; - ORTAssertNullableResultUnsuccessful(ortValue, err); -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/objectivec/test/testdata/gen_models.sh b/objectivec/test/testdata/gen_models.sh deleted file mode 100755 index 0a58ca8..0000000 --- a/objectivec/test/testdata/gen_models.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -set -e - -# Get directory this script is in -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -cd ${DIR} - -python3 ./single_add_gen.py - -ORT_CONVERT_ONNX_MODELS_TO_ORT_OPTIMIZATION_LEVEL=basic python3 -m onnxruntime.tools.convert_onnx_models_to_ort --optimization_style=Fixed . diff --git a/objectivec/test/testdata/single_add.basic.ort b/objectivec/test/testdata/single_add.basic.ort deleted file mode 100644 index f622784..0000000 Binary files a/objectivec/test/testdata/single_add.basic.ort and /dev/null differ diff --git a/objectivec/test/testdata/single_add.onnx b/objectivec/test/testdata/single_add.onnx deleted file mode 100644 index 82e8fe6..0000000 Binary files a/objectivec/test/testdata/single_add.onnx and /dev/null differ diff --git a/objectivec/test/testdata/single_add_gen.py b/objectivec/test/testdata/single_add_gen.py deleted file mode 100644 index 15b4372..0000000 --- a/objectivec/test/testdata/single_add_gen.py +++ /dev/null @@ -1,19 +0,0 @@ -import onnx -from onnx import TensorProto, helper - -graph = helper.make_graph( - [ # nodes - helper.make_node("Add", ["A", "B"], ["C"], "Add"), - ], - "SingleAdd", # name - [ # inputs - helper.make_tensor_value_info("A", TensorProto.FLOAT, [1]), - helper.make_tensor_value_info("B", TensorProto.FLOAT, [1]), - ], - [ # outputs - helper.make_tensor_value_info("C", TensorProto.FLOAT, [1]), - ], -) - -model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 12)]) -onnx.save(model, r"single_add.onnx")