diff --git a/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm b/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm index c6da7750a11..a64d977bb26 100644 --- a/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm +++ b/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm @@ -711,14 +711,15 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle loggingOptions:(const executorchcoreml::ModelLoggingOptions&)loggingOptions eventLogger:(const executorchcoreml::ModelEventLogger* _Nullable)eventLogger error:(NSError * __autoreleasing *)error { + BOOL result = NO; id executor = [self executorWithHandle:handle]; if (!executor) { ETCoreMLLogErrorAndSetNSError(error, ETCoreMLErrorInternalError, "Model is already unloaded."); - return NO; + return result; } - + ETCoreMLModel *model = executor.model; if (args.count != model.orderedInputNames.count + model.orderedOutputNames.count) { ETCoreMLLogErrorAndSetNSError(error, @@ -726,8 +727,9 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle "Model is invalid, expected args count to be %lu but got %lu.", static_cast(model.orderedInputNames.count + model.orderedOutputNames.count), args.count); - return NO; + return result; } + NSError *localError = nil; @autoreleasepool { NSArray *inputs = [args subarrayWithRange:NSMakeRange(0, model.orderedInputNames.count)]; NSArray *outputs = [args subarrayWithRange:NSMakeRange(model.orderedInputNames.count, args.count - model.orderedInputNames.count)]; @@ -735,21 +737,23 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle if (executor.ignoreOutputBackings == NO) { outputBackings = outputs; } - NSArray *modelOutputs = [self executeModelUsingExecutor:executor inputs:inputs outputBackings:outputBackings loggingOptions:loggingOptions eventLogger:eventLogger - error:error]; - if (!modelOutputs) { - return NO; + error:&localError]; + if (modelOutputs) { + ::set_outputs(outputs, modelOutputs); + result = YES; } - - ::set_outputs(outputs, modelOutputs); } - - return YES; + if (!result) { + if (error) { + *error = localError; + } + } + return result; } - (BOOL)executeModelWithHandle:(ModelHandle *)handle @@ -757,14 +761,14 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle loggingOptions:(const executorchcoreml::ModelLoggingOptions&)loggingOptions eventLogger:(const executorchcoreml::ModelEventLogger* _Nullable)eventLogger error:(NSError * __autoreleasing *)error { + BOOL result = NO; id executor = [self executorWithHandle:handle]; if (!executor) { ETCoreMLLogErrorAndSetNSError(error, ETCoreMLErrorInternalError, "Model is already unloaded."); - return NO; + return result; } - ETCoreMLModel *model = executor.model; if (argsVec.size() != model.orderedInputNames.count + model.orderedOutputNames.count) { ETCoreMLLogErrorAndSetNSError(error, @@ -772,45 +776,44 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle "Model is invalid, expected args count to be %lu but got %lu.", static_cast(model.orderedInputNames.count + model.orderedOutputNames.count), argsVec.size()); - return NO; + return result; } - std::vector inputArgs(argsVec.begin(), argsVec.begin() + model.orderedInputNames.count); std::vector outputArgs(argsVec.begin() + model.orderedInputNames.count, argsVec.end()); + NSError *localError = nil; @autoreleasepool { - NSArray *inputs = [model prepareInputs:inputArgs error:error]; - if (!inputs) { - return NO; - } - - NSArray *outputBackings = @[]; - if (executor.ignoreOutputBackings == NO) { - outputBackings = [model prepareOutputBackings:outputArgs error:error]; - } - - if (!outputBackings) { - return NO; - } - - NSArray *modelOutputs = [self executeModelUsingExecutor:executor - inputs:inputs - outputBackings:outputBackings - loggingOptions:loggingOptions - eventLogger:eventLogger - error:error]; - if (!modelOutputs) { - return NO; + NSArray *inputs = [model prepareInputs:inputArgs error:&localError]; + if (inputs) { + NSArray *outputBackings = @[]; + if (executor.ignoreOutputBackings == NO) { + outputBackings = [model prepareOutputBackings:outputArgs error:&localError]; + } + if (outputBackings) { + NSArray *modelOutputs = [self executeModelUsingExecutor:executor + inputs:inputs + outputBackings:outputBackings + loggingOptions:loggingOptions + eventLogger:eventLogger + error:&localError]; + if (modelOutputs) { + // Resize for dynamic shapes + for (int i = 0; i < outputArgs.size(); i++) { + auto new_size = to_vector(modelOutputs[i].shape); + outputArgs[i].resize(new_size); + argsVec[model.orderedInputNames.count + i].resize(new_size); + } + ::set_outputs(outputArgs, modelOutputs); + result = YES; + } + } } - - // Resize for dynamic shapes - for (int i = 0; i < outputArgs.size(); i++) { - auto new_size = to_vector(modelOutputs[i].shape); - outputArgs[i].resize(new_size); - argsVec[model.orderedInputNames.count + i].resize(new_size); + } + if (!result) { + if (error) { + *error = localError; } - ::set_outputs(outputArgs, modelOutputs); - return YES; } + return result; } - (BOOL)unloadModelWithHandle:(ModelHandle *)handle { diff --git a/backends/apple/coreml/runtime/delegate/MLModel_Prewarm.mm b/backends/apple/coreml/runtime/delegate/MLModel_Prewarm.mm index 6a737d1e82b..45b82bd52fc 100644 --- a/backends/apple/coreml/runtime/delegate/MLModel_Prewarm.mm +++ b/backends/apple/coreml/runtime/delegate/MLModel_Prewarm.mm @@ -107,26 +107,29 @@ + (MLMultiArray *)zeroedMultiArrayWithShape:(NSArray *)shape @implementation MLModel (Prewarm) - (BOOL)prewarmUsingState:(nullable id)state error:(NSError * __autoreleasing *)error { + NSError *localError = nil; + BOOL result = NO; @autoreleasepool { - id inputs = ::get_zeroed_inputs(self, error); - if (!inputs) { - return NO; - } - - - id outputs = nil; - if (state != nil) { + id inputs = ::get_zeroed_inputs(self, &localError); + if (inputs) { + id outputs = nil; + if (state) { #if MODEL_STATE_IS_SUPPORTED - if (@available(macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, *)) { - outputs = [self predictionFromFeatures:inputs usingState:(MLState *)state error:error]; - return outputs != nil; - } + if (@available(macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, *)) { + outputs = [self predictionFromFeatures:inputs usingState:(MLState *)state error:&localError]; + } #endif + } + if (!outputs) { + outputs = [self predictionFromFeatures:inputs error:&localError]; + } + result = outputs != nil; } - - outputs = [self predictionFromFeatures:inputs error:error]; - return outputs != nil; } + if (!result && error) { + *error = localError; + } + return result; } diff --git a/backends/apple/coreml/runtime/sdk/ETCoreMLModelAnalyzer.mm b/backends/apple/coreml/runtime/sdk/ETCoreMLModelAnalyzer.mm index 87e086c5bbd..7d9a51fdffc 100644 --- a/backends/apple/coreml/runtime/sdk/ETCoreMLModelAnalyzer.mm +++ b/backends/apple/coreml/runtime/sdk/ETCoreMLModelAnalyzer.mm @@ -138,7 +138,8 @@ - (nullable instancetype)initWithCompiledModelAsset:(ETCoreMLAsset *)compiledMod if (!self.debugger) { return nil; } - + + NSError *localError = nil; NSArray *modelOutputs = nil; NSArray *operationPaths = self.debugger.operationPaths; NSDictionary *operationPathToDebugSymbolMap = self.debugger.operationPathToDebugSymbolMap; @@ -150,8 +151,11 @@ - (nullable instancetype)initWithCompiledModelAsset:(ETCoreMLAsset *)compiledMod options:predictionOptions inputs:inputs modelOutputs:&modelOutputs - error:error]; + error:&localError]; if (!outputs) { + if (error) { + *error = localError; + } return nil; } diff --git a/backends/apple/coreml/runtime/sdk/ETCoreMLModelDebugger.mm b/backends/apple/coreml/runtime/sdk/ETCoreMLModelDebugger.mm index 1cac0de40f3..91a0b1a63fa 100644 --- a/backends/apple/coreml/runtime/sdk/ETCoreMLModelDebugger.mm +++ b/backends/apple/coreml/runtime/sdk/ETCoreMLModelDebugger.mm @@ -661,9 +661,15 @@ - (nullable ETCoreMLAsset *)compiledModelAssetWithOutputsAtPaths:(NSArray *)modelsWithOutputsOfOperationsAtPath:(NSArray *)paths error:(NSError* __autoreleasing *)error { + NSError *localError = nil; + NSArray *result = nil; @autoreleasepool { - return [self _modelsWithOutputsOfOperationsAtPath:paths error:error]; + result = [self _modelsWithOutputsOfOperationsAtPath:paths error:&localError]; + } + if (!result && error) { + *error = localError; } + return result; } - (nullable ETCoreMLModelOutputs *)outputsOfOperationsAtPaths:(NSArray *)paths @@ -671,27 +677,30 @@ - (nullable ETCoreMLModelOutputs *)outputsOfOperationsAtPaths:(NSArray)inputs modelOutputs:(NSArray *_Nullable __autoreleasing *_Nonnull)modelOutputs error:(NSError* __autoreleasing *)error { - NSArray *lModelOutputs = nil; - NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:paths.count]; + NSError *localError = nil; + BOOL success = NO; + NSArray *localModelOutputs = nil; + ETCoreMLModelOutputs *result = [NSMutableDictionary dictionaryWithCapacity:paths.count]; @autoreleasepool { - NSArray *models = [self modelsWithOutputsOfOperationsAtPath:paths error:error]; - if (!models) { - return nil; - } - - for (DebuggableModel *pair in models) { - id outputFeatures = [pair.first predictionFromFeatures:inputs options:options error:error]; - set_intermediate_outputs(outputFeatures, paths, result); - if (modelOutputs) { - set_model_outputs(outputFeatures, self.outputNames, &lModelOutputs); - } + NSArray *models = [self modelsWithOutputsOfOperationsAtPath:paths error:&localError]; + success = models != nil; + if (success) { + for (DebuggableModel *pair in models) { + id outputFeatures = [pair.first predictionFromFeatures:inputs options:options error:&localError]; + set_intermediate_outputs(outputFeatures, paths, result); + if (modelOutputs) { + set_model_outputs(outputFeatures, self.outputNames, &localModelOutputs); + } + } } } - + if (!success && error) { + *error = localError; + return nil; + } if (modelOutputs) { - *modelOutputs = lModelOutputs; + *modelOutputs = localModelOutputs; } - return result; }