Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 48 additions & 45 deletions backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -711,106 +711,109 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle
loggingOptions:(const executorchcoreml::ModelLoggingOptions&)loggingOptions
eventLogger:(const executorchcoreml::ModelEventLogger* _Nullable)eventLogger
error:(NSError * __autoreleasing *)error {
BOOL result = NO;
id<ETCoreMLModelExecutor> 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,
ETCoreMLErrorCorruptedModel,
"Model is invalid, expected args count to be %lu but got %lu.",
static_cast<unsigned long>(model.orderedInputNames.count + model.orderedOutputNames.count),
args.count);
return NO;
return result;
}
NSError *localError = nil;
@autoreleasepool {
NSArray<MLMultiArray *> *inputs = [args subarrayWithRange:NSMakeRange(0, model.orderedInputNames.count)];
NSArray<MLMultiArray *> *outputs = [args subarrayWithRange:NSMakeRange(model.orderedInputNames.count, args.count - model.orderedInputNames.count)];
NSArray<MLMultiArray *> *outputBackings = @[];
if (executor.ignoreOutputBackings == NO) {
outputBackings = outputs;
}

NSArray<MLMultiArray *> *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
argsVec:(std::vector<executorchcoreml::MultiArray>&)argsVec
loggingOptions:(const executorchcoreml::ModelLoggingOptions&)loggingOptions
eventLogger:(const executorchcoreml::ModelEventLogger* _Nullable)eventLogger
error:(NSError * __autoreleasing *)error {
BOOL result = NO;
id<ETCoreMLModelExecutor> 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,
ETCoreMLErrorCorruptedModel,
"Model is invalid, expected args count to be %lu but got %lu.",
static_cast<unsigned long>(model.orderedInputNames.count + model.orderedOutputNames.count),
argsVec.size());
return NO;
return result;
}

std::vector<executorchcoreml::MultiArray> inputArgs(argsVec.begin(), argsVec.begin() + model.orderedInputNames.count);
std::vector<executorchcoreml::MultiArray> outputArgs(argsVec.begin() + model.orderedInputNames.count, argsVec.end());
NSError *localError = nil;
@autoreleasepool {
NSArray<MLMultiArray *> *inputs = [model prepareInputs:inputArgs error:error];
if (!inputs) {
return NO;
}

NSArray<MLMultiArray *> *outputBackings = @[];
if (executor.ignoreOutputBackings == NO) {
outputBackings = [model prepareOutputBackings:outputArgs error:error];
}

if (!outputBackings) {
return NO;
}

NSArray<MLMultiArray *> *modelOutputs = [self executeModelUsingExecutor:executor
inputs:inputs
outputBackings:outputBackings
loggingOptions:loggingOptions
eventLogger:eventLogger
error:error];
if (!modelOutputs) {
return NO;
NSArray<MLMultiArray *> *inputs = [model prepareInputs:inputArgs error:&localError];
if (inputs) {
NSArray<MLMultiArray *> *outputBackings = @[];
if (executor.ignoreOutputBackings == NO) {
outputBackings = [model prepareOutputBackings:outputArgs error:&localError];
}
if (outputBackings) {
NSArray<MLMultiArray *> *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<size_t>(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<size_t>(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 {
Expand Down
33 changes: 18 additions & 15 deletions backends/apple/coreml/runtime/delegate/MLModel_Prewarm.mm
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,29 @@ + (MLMultiArray *)zeroedMultiArrayWithShape:(NSArray<NSNumber *> *)shape
@implementation MLModel (Prewarm)

- (BOOL)prewarmUsingState:(nullable id)state error:(NSError * __autoreleasing *)error {
NSError *localError = nil;
BOOL result = NO;
@autoreleasepool {
id<MLFeatureProvider> inputs = ::get_zeroed_inputs(self, error);
if (!inputs) {
return NO;
}


id<MLFeatureProvider> outputs = nil;
if (state != nil) {
id<MLFeatureProvider> inputs = ::get_zeroed_inputs(self, &localError);
if (inputs) {
id<MLFeatureProvider> 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;
}


Expand Down
8 changes: 6 additions & 2 deletions backends/apple/coreml/runtime/sdk/ETCoreMLModelAnalyzer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ - (nullable instancetype)initWithCompiledModelAsset:(ETCoreMLAsset *)compiledMod
if (!self.debugger) {
return nil;
}


NSError *localError = nil;
NSArray<MLMultiArray *> *modelOutputs = nil;
NSArray<ETCoreMLModelStructurePath *> *operationPaths = self.debugger.operationPaths;
NSDictionary<ETCoreMLModelStructurePath *, NSString *> *operationPathToDebugSymbolMap = self.debugger.operationPathToDebugSymbolMap;
Expand All @@ -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;
}

Expand Down
43 changes: 26 additions & 17 deletions backends/apple/coreml/runtime/sdk/ETCoreMLModelDebugger.mm
Original file line number Diff line number Diff line change
Expand Up @@ -661,37 +661,46 @@ - (nullable ETCoreMLAsset *)compiledModelAssetWithOutputsAtPaths:(NSArray<ETCore

- (nullable NSArray<DebuggableModel *> *)modelsWithOutputsOfOperationsAtPath:(NSArray<ETCoreMLModelStructurePath *> *)paths
error:(NSError* __autoreleasing *)error {
NSError *localError = nil;
NSArray<DebuggableModel *> *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<ETCoreMLModelStructurePath *> *)paths
options:(MLPredictionOptions *)options
inputs:(id<MLFeatureProvider>)inputs
modelOutputs:(NSArray<MLMultiArray *> *_Nullable __autoreleasing *_Nonnull)modelOutputs
error:(NSError* __autoreleasing *)error {
NSArray<MLMultiArray *> *lModelOutputs = nil;
NSMutableDictionary<ETCoreMLModelStructurePath *, MLMultiArray *> *result = [NSMutableDictionary dictionaryWithCapacity:paths.count];
NSError *localError = nil;
BOOL success = NO;
NSArray<MLMultiArray *> *localModelOutputs = nil;
ETCoreMLModelOutputs *result = [NSMutableDictionary dictionaryWithCapacity:paths.count];
@autoreleasepool {
NSArray<DebuggableModel *> *models = [self modelsWithOutputsOfOperationsAtPath:paths error:error];
if (!models) {
return nil;
}

for (DebuggableModel *pair in models) {
id<MLFeatureProvider> 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<DebuggableModel *> *models = [self modelsWithOutputsOfOperationsAtPath:paths error:&localError];
success = models != nil;
if (success) {
for (DebuggableModel *pair in models) {
id<MLFeatureProvider> 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;
}

Expand Down
Loading