From 6c5bb97d88a2a9e71081f39e7528aea8348ce0a3 Mon Sep 17 00:00:00 2001 From: Gyanendra Sinha Date: Wed, 20 Aug 2025 13:02:02 -0700 Subject: [PATCH 1/3] Improve asset management --- .../runtime/delegate/ETCoreMLAssetManager.h | 17 ++ .../runtime/delegate/ETCoreMLAssetManager.mm | 89 +++++--- .../runtime/delegate/ETCoreMLModelLoader.mm | 19 +- .../runtime/delegate/ETCoreMLModelManager.mm | 198 +++++++++++------- 4 files changed, 207 insertions(+), 116 deletions(-) diff --git a/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h b/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h index 11d957044e9..006056a591f 100644 --- a/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h +++ b/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h @@ -99,6 +99,17 @@ NS_ASSUME_NONNULL_BEGIN - (NSUInteger)compact:(NSUInteger)sizeInBytes error:(NSError* __autoreleasing*)error; +/// Executes a block with a unique temporary directory. +/// +/// A new temporary subdirectory URL is created inside the receiver’s designated +/// base directory. The directory is passed to the block, which can use it to +/// perform temporary file operations. After the block finishes executing, +/// the directory and its contents are removed. +/// +/// @param block A block to execute. The block receives a unique URL. +- (void)withTemporaryDirectory:(void (^)(NSURL *directoryURL))block; + + /// Purges the assets storage. The assets are moved to the trash directory and are asynchronously /// deleted. /// @@ -117,6 +128,12 @@ NS_ASSUME_NONNULL_BEGIN /// contents are deleted asynchronously. @property (copy, readonly, nonatomic) NSURL* trashDirectoryURL; + +/// The staging directory URL, used to hold assets that are being prepared or processed +/// before they are moved into their final location. The contents of this directory +/// are temporary and may be cleared when no longer needed. +@property (copy, readonly, nonatomic) NSURL* stagingDirectoryURL; + /// The file manager. @property (strong, readonly, nonatomic) NSFileManager* fileManager; diff --git a/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.mm b/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.mm index 256026e1f09..49d16214980 100644 --- a/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.mm +++ b/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.mm @@ -254,6 +254,18 @@ BOOL is_asset_alive(NSMapTable *assets_in_use_map, return assets; } + +NSURL * _Nullable move_to_directory(NSURL *url, + NSURL *directoryURL, + NSFileManager *fileManager, + NSError * __autoreleasing *error) { + NSURL *dstURL = [directoryURL URLByAppendingPathComponent:[NSUUID UUID].UUIDString]; + if (![fileManager moveItemAtURL:url toURL:dstURL error:error]) { + return nil; + } + return dstURL; +} + } //namespace @interface ETCoreMLAssetManager () { @@ -299,12 +311,20 @@ - (nullable instancetype)initWithDatabase:(const std::shared_ptr&)data if (!managedAssetsDirectoryURL) { return nil; } - + NSURL *managedTrashDirectoryURL = ::create_directory_if_needed(trashDirectoryURL, @"models", fileManager, error); if (!managedTrashDirectoryURL) { return nil; } - + + // Remove any existing contents in the staging directory by moving them to the trash directory, + // then recreate a clean staging directory for new use. + move_to_directory([assetsDirectoryURL URLByAppendingPathComponent:@"staging"], managedTrashDirectoryURL, fileManager, nil); + NSURL *managedStagingDirectoryURL = ::create_directory_if_needed(assetsDirectoryURL, @"staging", fileManager, error); + if (!managedStagingDirectoryURL) { + return nil; + } + // If directory is empty then purge the stores if (::is_directory_empty(managedAssetsDirectoryURL, fileManager, nil)) { assetsMetaStore.impl()->purge(ec); @@ -315,6 +335,7 @@ - (nullable instancetype)initWithDatabase:(const std::shared_ptr&)data _assetsStore = std::move(assetsStore); _assetsMetaStore = std::move(assetsMetaStore); _assetsDirectoryURL = managedAssetsDirectoryURL; + _stagingDirectoryURL = managedStagingDirectoryURL; _trashDirectoryURL = managedTrashDirectoryURL; _estimatedSizeInBytes = sizeInBytes.value(); _maxAssetsSizeInBytes = maxAssetsSizeInBytes; @@ -349,12 +370,18 @@ - (nullable instancetype)initWithDatabaseURL:(NSURL *)databaseURL - (nullable NSURL *)moveURL:(NSURL *)url toUniqueURLInDirectory:(NSURL *)directoryURL error:(NSError * __autoreleasing *)error { - NSURL *dstURL = [directoryURL URLByAppendingPathComponent:[NSUUID UUID].UUIDString]; - if (![self.fileManager moveItemAtURL:url toURL:dstURL error:error]) { - return nil; + return move_to_directory(url, directoryURL, self.fileManager, error); +} + +- (void)withTemporaryDirectory:(void (^)(NSURL *directoryURL))block { + NSURL *dstURL = [self.stagingDirectoryURL URLByAppendingPathComponent:[NSUUID UUID].UUIDString]; + block(dstURL); + if (![self.fileManager fileExistsAtPath:dstURL.path]) { + return; } - - return dstURL; + + [self moveURL:dstURL toUniqueURLInDirectory:self.trashDirectoryURL error:nil]; + [self cleanupTrashDirectory]; } - (void)cleanupAssetIfNeeded:(ETCoreMLAsset *)asset { @@ -407,7 +434,7 @@ - (nullable ETCoreMLAsset *)_storeAssetAtURL:(NSURL *)srcURL return false; } - // If an asset exists move it + // If an asset exists move it, [self moveURL:dstURL toUniqueURLInDirectory:self.trashDirectoryURL error:nil]; // Move the asset to assets directory. @@ -433,16 +460,25 @@ - (nullable ETCoreMLAsset *)_storeAssetAtURL:(NSURL *)srcURL } - (void)triggerCompaction { - if (self.estimatedSizeInBytes < self.maxAssetsSizeInBytes) { - return; + if (self.estimatedSizeInBytes >= self.maxAssetsSizeInBytes) { + __weak __typeof(self) weakSelf = self; + dispatch_async(self.syncQueue, ^{ + NSError *localError = nil; + if (![weakSelf _compact:self.maxAssetsSizeInBytes error:&localError]) { + ETCoreMLLogError(localError, "Failed to compact asset store."); + } + }); } - + + // Always clean the trash directory to ensure a minimal footprint. + // The `trashQueue` is serialized, so only one cleanup will run at a time. + [self cleanupTrashDirectory]; +} + +- (void)cleanupTrashDirectory { __weak __typeof(self) weakSelf = self; - dispatch_async(self.syncQueue, ^{ - NSError *localError = nil; - if (![weakSelf _compact:self.maxAssetsSizeInBytes error:&localError]) { - ETCoreMLLogError(localError, "Failed to compact asset store."); - } + dispatch_async(self.trashQueue, ^{ + [weakSelf removeFilesInTrashDirectory]; }); } @@ -649,13 +685,7 @@ - (NSUInteger)_compact:(NSUInteger)sizeInBytes error:(NSError * __autoreleasing identifier); } } - - // Trigger cleanup. - __weak __typeof(self) weakSelf = self; - dispatch_async(self.trashQueue, ^{ - [weakSelf removeFilesInTrashDirectory]; - }); - + return _estimatedSizeInBytes; } @@ -664,7 +694,10 @@ - (NSUInteger)compact:(NSUInteger)sizeInBytes error:(NSError * __autoreleasing * dispatch_sync(self.syncQueue, ^{ result = [self _compact:sizeInBytes error:error]; }); - + + // Always clean the trash directory to ensure a minimal footprint. + // The `trashQueue` is serialized, so only one cleanup will run at a time. + [self cleanupTrashDirectory]; return result; } @@ -724,13 +757,7 @@ - (BOOL)_purge:(NSError * __autoreleasing *)error { ::set_error_from_error_code(ec, error); // Trigger cleanup - if (status) { - __weak __typeof(self) weakSelf = self; - dispatch_async(self.trashQueue, ^{ - [weakSelf removeFilesInTrashDirectory]; - }); - } - + [self cleanupTrashDirectory]; return static_cast(status); } diff --git a/backends/apple/coreml/runtime/delegate/ETCoreMLModelLoader.mm b/backends/apple/coreml/runtime/delegate/ETCoreMLModelLoader.mm index 05aa910d954..9e8ae04842e 100644 --- a/backends/apple/coreml/runtime/delegate/ETCoreMLModelLoader.mm +++ b/backends/apple/coreml/runtime/delegate/ETCoreMLModelLoader.mm @@ -62,21 +62,12 @@ + (nullable ETCoreMLModel *)loadModelWithContentsOfURL:(NSURL *)compiledModelURL if (model) { return model; } - - if (localError) { - ETCoreMLLogError(localError, - "Failed to load model from compiled asset with identifier = %@", - identifier); - } - - // If store failed then we will load the model from compiledURL. - auto backingAsset = Asset::make(compiledModelURL, identifier, assetManager.fileManager, error); - if (!backingAsset) { - return nil; + + if (error) { + *error = localError; } - - asset = [[ETCoreMLAsset alloc] initWithBackingAsset:backingAsset.value()]; - return ::get_model_from_asset(asset, configuration, metadata, error); + + return nil; } @end diff --git a/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm b/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm index f4cfd2146ac..43b3325d062 100644 --- a/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm +++ b/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm @@ -345,6 +345,10 @@ void add_compute_unit(std::string& identifier, MLComputeUnits compute_units) { return [ETCoreMLModelDebugInfo modelDebugInfoFromData:file_data error:error]; } +NSString *raw_model_identifier(NSString *identifier) { + return [NSString stringWithFormat:@"raw_%@", identifier]; +} + #endif } //namespace @@ -408,7 +412,7 @@ - (nullable ETCoreMLAsset *)assetWithIdentifier:(NSString *)identifier { return modelAsset; } - NSError *localError = nil; + __block NSError *localError = nil; modelAsset = [self.assetManager assetWithIdentifier:identifier error:&localError]; if (localError) { ETCoreMLLogError(localError, @@ -420,8 +424,9 @@ - (nullable ETCoreMLAsset *)assetWithIdentifier:(NSString *)identifier { } - (nullable NSURL *)compiledModelURLWithIdentifier:(NSString *)identifier + modelURL:(nullable NSURL *)modelURL inMemoryFS:(const inmemoryfs::InMemoryFileSystem*)inMemoryFS - assetManager:(ETCoreMLAssetManager *)assetManager + dstURL:(NSURL *)dstURL error:(NSError * __autoreleasing *)error { auto modelAssetType = get_model_asset_type(inMemoryFS); if (!modelAssetType) { @@ -430,78 +435,134 @@ - (nullable NSURL *)compiledModelURLWithIdentifier:(NSString *)identifier "AOT blob is missing model file."); return nil; } - - NSURL *dstURL = [self.assetManager.trashDirectoryURL URLByAppendingPathComponent:[NSUUID UUID].UUIDString]; - NSURL *modelURL = ::write_model_files(dstURL, self.fileManager, identifier, modelAssetType.value(), inMemoryFS, error); + + // If modelURL is not provided, write model files to the destination directory (dstURL) + // and obtain a URL pointing to them. Otherwise, use the provided modelURL. + modelURL = (modelURL == nil) ? ::write_model_files(dstURL, self.fileManager, identifier, modelAssetType.value(), inMemoryFS, error) : modelURL; + if (!modelURL) { + // Failed to generate or locate model files, return nil. + return nil; + } + + // Handle based on the type of the model asset. switch (modelAssetType.value()) { case ModelAssetType::CompiledModel: { - // Model is already compiled. + // The model is already compiled; no further action needed. + // Return the existing model URL. return modelURL; } - + case ModelAssetType::Model: { - // Compile the model. + // The model is not compiled yet. + // Compile the model at the specified URL with a maximum wait time of 5 minutes. NSURL *compiledModelURL = [ETCoreMLModelCompiler compileModelAtURL:modelURL maxWaitTimeInSeconds:(5 * 60) error:error]; - + // Return the URL of the compiled model or nil if compilation fails. return compiledModelURL; } } } -#if ET_EVENT_TRACER_ENABLED -- (nullable id)modelExecutorWithMetadata:(const ModelMetadata&)metadata - inMemoryFS:(const inmemoryfs::InMemoryFileSystem*)inMemoryFS - configuration:(MLModelConfiguration *)configuration - error:(NSError * __autoreleasing *)error { +- (nullable ETCoreMLAsset *)compiledModelAssetWithMetadata:(const ModelMetadata&)metadata + modelURL:(nullable NSURL *)modelURL + inMemoryFS:(const inmemoryfs::InMemoryFileSystem*)inMemoryFS + error:(NSError * __autoreleasing *)error { NSString *identifier = @(metadata.identifier.c_str()); - // Otherwise try to retrieve the compiled asset. - ETCoreMLAsset *compiledModelAsset = [self assetWithIdentifier:identifier]; + __block ETCoreMLAsset *compiledModelAsset = [self assetWithIdentifier:identifier]; if (compiledModelAsset) { - ETCoreMLLogInfo("Cache Hit: Successfully retrieved model with identifier=%@ from the models cache.", identifier); + ETCoreMLLogInfo("Cache Hit: Successfully retrieved compiled model with identifier=%@ from the models cache.", identifier); } else { - ETCoreMLLogInfo("Cache Miss: Model with identifier=%@ was not found in the models cache.", identifier); + ETCoreMLLogInfo("Cache Miss: Compiled Model with identifier=%@ was not found in the models cache.", identifier); } - - // Create a unique directory for writing model files. - NSURL *dstURL = [self.assetManager.trashDirectoryURL URLByAppendingPathComponent:[NSUUID UUID].UUIDString]; - auto modelAssetType = get_model_asset_type(inMemoryFS); - ETCoreMLAsset *modelAsset = nil; - // Write the model files. - if (modelAssetType == ModelAssetType::Model) { - NSURL *modelURL = ::write_model_files(dstURL, self.fileManager, identifier, modelAssetType.value(), inMemoryFS, error); - if (modelURL) { - modelAsset = make_asset(modelURL, - identifier, - self.fileManager, - error); + + [self.assetManager withTemporaryDirectory:^(NSURL * _Nonnull directoryURL) { + if (compiledModelAsset) { + return; } - } - - if (!compiledModelAsset) { - // Compile the model. + + // The directory specified by `directoryURL` is unique and will be automatically cleaned up + // once the enclosing block completes. NSURL *compiledModelURL = [self compiledModelURLWithIdentifier:identifier + modelURL:modelURL inMemoryFS:inMemoryFS - assetManager:self.assetManager + dstURL:directoryURL error:error]; - compiledModelAsset = make_asset(compiledModelURL, - identifier, - self.fileManager, - error); - } - - if (!compiledModelAsset) { - return nil; + if (compiledModelURL) { + // Move the compiled model to the asset manager to transfer ownership. + compiledModelAsset = [self.assetManager storeAssetAtURL:compiledModelURL withIdentifier:identifier error:error]; + } + }]; + + return compiledModelAsset; +} + +#if ET_EVENT_TRACER_ENABLED +- (nullable ETCoreMLAsset *)modelAssetWithMetadata:(const ModelMetadata&)metadata + inMemoryFS:(const inmemoryfs::InMemoryFileSystem*)inMemoryFS + error:(NSError * __autoreleasing *)error { + NSString *identifier = @(metadata.identifier.c_str()); + NSString *rawIdentifier = raw_model_identifier(identifier); + __block ETCoreMLAsset *modelAsset = [self assetWithIdentifier:rawIdentifier]; + if (modelAsset) { + ETCoreMLLogInfo("Cache Hit: Successfully retrieved model with identifier=%@ from the models cache.", identifier); + } else { + ETCoreMLLogInfo("Cache Miss: Model with identifier=%@ was not found in the models cache.", identifier); } - + + [self.assetManager withTemporaryDirectory:^(NSURL * _Nonnull directoryURL) { + if (modelAsset) { + return; + } + + auto modelAssetType = get_model_asset_type(inMemoryFS); + if (modelAssetType != ModelAssetType::Model) { + return; + } + + + ETCoreMLAsset *modelAsset = nil; + // The directory specified by `directoryURL` is unique and will be automatically cleaned up + // once the enclosing block completes. + NSURL *modelURL = ::write_model_files(directoryURL, + self.fileManager, + identifier, + modelAssetType.value(), + inMemoryFS, + error); + if (modelURL) { + // Move the model to the asset manager to transfer ownership. + modelAsset = [self.assetManager storeAssetAtURL:modelURL withIdentifier:rawIdentifier error:error]; + } + }]; + + return modelAsset; +} + +- (nullable id)modelExecutorWithMetadata:(const ModelMetadata&)metadata + inMemoryFS:(const inmemoryfs::InMemoryFileSystem*)inMemoryFS + configuration:(MLModelConfiguration *)configuration + error:(NSError * __autoreleasing *)error { NSError *localError = nil; - ETCoreMLModelDebugInfo *debug_info = get_model_debug_info(inMemoryFS, &localError); + ETCoreMLAsset *modelAsset = [self modelAssetWithMetadata:metadata inMemoryFS:inMemoryFS error:&localError]; if (localError) { - ETCoreMLLogError(localError, "Failed to parse debug info file"); + if (error) { + *error = localError; + } + + return nil; } - + ETCoreMLAsset *compiledModelAsset = [self compiledModelAssetWithMetadata:metadata + modelURL:modelAsset.contentURL + inMemoryFS:inMemoryFS + error:error]; + if (!compiledModelAsset) { + return nil; + } + + ETCoreMLModelDebugInfo *debug_info = get_model_debug_info(inMemoryFS, error); + // The analyzer requires both the raw (uncompiled) asset and the compiled model asset to perform analysis. return [[ETCoreMLModelAnalyzer alloc] initWithCompiledModelAsset:compiledModelAsset modelAsset:modelAsset modelDebugInfo:debug_info @@ -510,41 +571,33 @@ - (nullable NSURL *)compiledModelURLWithIdentifier:(NSString *)identifier assetManager:self.assetManager error:error]; } - #else - (nullable id)modelExecutorWithMetadata:(const ModelMetadata&)metadata inMemoryFS:(const inmemoryfs::InMemoryFileSystem*)inMemoryFS configuration:(MLModelConfiguration *)configuration error:(NSError * __autoreleasing *)error { - NSString *identifier = @(metadata.identifier.c_str()); - // Otherwise try to retrieve the compiled asset. - ETCoreMLAsset *asset = [self assetWithIdentifier:identifier]; - ETCoreMLModel *model = asset ? get_model_from_asset(asset, configuration, metadata, error) : nil; - if (model) { - ETCoreMLLogInfo("Cache Hit: Successfully retrieved model with identifier=%@ from the models cache.", identifier); - return [[ETCoreMLDefaultModelExecutor alloc] initWithModel:model]; + ETCoreMLAsset *compiledModelAsset = [self compiledModelAssetWithMetadata:metadata + modelURL:nil + inMemoryFS:inMemoryFS + error:error]; + if (!compiledModelAsset) { + return nil; } - - ETCoreMLLogInfo("Cache Miss: Model with identifier=%@ was not found in the models cache.", identifier); - // Compile the model. - NSURL *compiledModelURL = [self compiledModelURLWithIdentifier:identifier - inMemoryFS:inMemoryFS - assetManager:self.assetManager - error:error]; - if (!compiledModelURL) { + + ETCoreMLModel *model = [ETCoreMLModelLoader loadModelWithContentsOfURL:compiledModelAsset.contentURL + configuration:configuration + metadata:metadata + assetManager:self.assetManager + error:error]; + if (!model) { return nil; } - - model = [ETCoreMLModelLoader loadModelWithContentsOfURL:compiledModelURL - configuration:configuration - metadata:metadata - assetManager:self.assetManager - error:error]; - + return [[ETCoreMLDefaultModelExecutor alloc] initWithModel:model]; } #endif + - (nullable id)_modelExecutorWithAOTData:(NSData *)data configuration:(MLModelConfiguration *)configuration error:(NSError * __autoreleasing *)error { @@ -729,6 +782,7 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle args.count); return result; } + NSError *localError = nil; @autoreleasepool { NSArray *inputs = [args subarrayWithRange:NSMakeRange(0, model.orderedInputNames.count)]; @@ -748,11 +802,13 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle result = YES; } } + if (!result) { if (error) { *error = localError; } } + return result; } From e1187a1d4cd173a56ce18e878226613ea8613e84 Mon Sep 17 00:00:00 2001 From: Gyanendra Sinha Date: Thu, 21 Aug 2025 11:52:49 -0700 Subject: [PATCH 2/3] Address comemnts --- .../runtime/delegate/ETCoreMLAssetManager.mm | 31 ++++++++++--------- .../runtime/delegate/ETCoreMLModelManager.mm | 8 ++--- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.mm b/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.mm index 49d16214980..53c3d1cdc69 100644 --- a/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.mm +++ b/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.mm @@ -259,10 +259,21 @@ BOOL is_asset_alive(NSMapTable *assets_in_use_map, NSURL *directoryURL, NSFileManager *fileManager, NSError * __autoreleasing *error) { + if (!url) { + ETCoreMLLogErrorAndSetNSError(error, ETCoreMLErrorInternalError, "Move operation failed: source URL is nil."); + return nil; + } + + if (!directoryURL) { + ETCoreMLLogErrorAndSetNSError(error, ETCoreMLErrorInternalError, "Move operation failed: destination URL is nil."); + return nil; + } + NSURL *dstURL = [directoryURL URLByAppendingPathComponent:[NSUUID UUID].UUIDString]; if (![fileManager moveItemAtURL:url toURL:dstURL error:error]) { return nil; } + return dstURL; } @@ -317,9 +328,6 @@ - (nullable instancetype)initWithDatabase:(const std::shared_ptr&)data return nil; } - // Remove any existing contents in the staging directory by moving them to the trash directory, - // then recreate a clean staging directory for new use. - move_to_directory([assetsDirectoryURL URLByAppendingPathComponent:@"staging"], managedTrashDirectoryURL, fileManager, nil); NSURL *managedStagingDirectoryURL = ::create_directory_if_needed(assetsDirectoryURL, @"staging", fileManager, error); if (!managedStagingDirectoryURL) { return nil; @@ -367,12 +375,6 @@ - (nullable instancetype)initWithDatabaseURL:(NSURL *)databaseURL error:error]; } -- (nullable NSURL *)moveURL:(NSURL *)url - toUniqueURLInDirectory:(NSURL *)directoryURL - error:(NSError * __autoreleasing *)error { - return move_to_directory(url, directoryURL, self.fileManager, error); -} - - (void)withTemporaryDirectory:(void (^)(NSURL *directoryURL))block { NSURL *dstURL = [self.stagingDirectoryURL URLByAppendingPathComponent:[NSUUID UUID].UUIDString]; block(dstURL); @@ -380,7 +382,7 @@ - (void)withTemporaryDirectory:(void (^)(NSURL *directoryURL))block { return; } - [self moveURL:dstURL toUniqueURLInDirectory:self.trashDirectoryURL error:nil]; + move_to_directory(dstURL, self.trashDirectoryURL, self.fileManager, nil); [self cleanupTrashDirectory]; } @@ -434,9 +436,8 @@ - (nullable ETCoreMLAsset *)_storeAssetAtURL:(NSURL *)srcURL return false; } - // If an asset exists move it, - [self moveURL:dstURL toUniqueURLInDirectory:self.trashDirectoryURL error:nil]; - + // If a file already exists at `dstURL`, move it to the trash for removal. + move_to_directory(dstURL, self.trashDirectoryURL, self.fileManager, nil); // Move the asset to assets directory. if (![self.fileManager moveItemAtURL:srcURL toURL:dstURL error:error]) { return false; @@ -584,7 +585,7 @@ - (BOOL)_removeAssetWithIdentifier:(NSString *)identifier NSURL *assetURL = ::get_asset_url(assetValue); if ([self.fileManager fileExistsAtPath:assetURL.path] && - ![self moveURL:assetURL toUniqueURLInDirectory:self.trashDirectoryURL error:error]) { + !move_to_directory(assetURL, self.trashDirectoryURL, self.fileManager, error)) { return false; } @@ -741,7 +742,7 @@ - (BOOL)_purge:(NSError * __autoreleasing *)error { } // Move the the whole assets directory to the temp directory. - if (![self moveURL:self.assetsDirectoryURL toUniqueURLInDirectory:self.trashDirectoryURL error:error]) { + if (!move_to_directory(self.assetsDirectoryURL, self.trashDirectoryURL, self.fileManager, error)) { return false; } diff --git a/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm b/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm index 43b3325d062..c27b42566dc 100644 --- a/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm +++ b/backends/apple/coreml/runtime/delegate/ETCoreMLModelManager.mm @@ -520,8 +520,6 @@ - (nullable ETCoreMLAsset *)modelAssetWithMetadata:(const ModelMetadata&)metadat return; } - - ETCoreMLAsset *modelAsset = nil; // The directory specified by `directoryURL` is unique and will be automatically cleaned up // once the enclosing block completes. NSURL *modelURL = ::write_model_files(directoryURL, @@ -803,10 +801,8 @@ - (BOOL)executeModelWithHandle:(ModelHandle *)handle } } - if (!result) { - if (error) { - *error = localError; - } + if (localError && error) { + *error = localError; } return result; From 0541ad99b115818c68e7fb3c81197c9e50ae4a9a Mon Sep 17 00:00:00 2001 From: Scott Roy <161522778+metascroy@users.noreply.github.com> Date: Fri, 22 Aug 2025 14:56:16 -0700 Subject: [PATCH 3/3] lint --- backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h b/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h index 006056a591f..a9e06efa90d 100644 --- a/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h +++ b/backends/apple/coreml/runtime/delegate/ETCoreMLAssetManager.h @@ -107,7 +107,7 @@ NS_ASSUME_NONNULL_BEGIN /// the directory and its contents are removed. /// /// @param block A block to execute. The block receives a unique URL. -- (void)withTemporaryDirectory:(void (^)(NSURL *directoryURL))block; +- (void)withTemporaryDirectory:(void (^)(NSURL* directoryURL))block; /// Purges the assets storage. The assets are moved to the trash directory and are asynchronously