当应用程序进入后台时,应用程序在前台使用带有 GPU 的 CoreML 无法切换到 CPU
Posted
技术标签:
【中文标题】当应用程序进入后台时,应用程序在前台使用带有 GPU 的 CoreML 无法切换到 CPU【英文标题】:App uses CoreML with GPU in the foreground fails to switch to CPU when app goes to background 【发布时间】:2019-07-23 03:54:17 【问题描述】:我正在使用 Swift 在 ios 应用程序中实现 CoreML。在前台时,我希望 CoreML 使用 GPU 来增强性能,但是当切换到后台时,CoreML 应该使用 CPU,因为在 iOS 中,GPU 无法在后台运行。
但是,在后台,GPU 抛出权限错误,说没有权限在后台使用 GPU。但是在代码中,我已经注册 CoreML 以仅在应用程序处于后台时才使用 CPU,但似乎 CoreML 类没有读取参数。
CoreML 在后台运行时出现错误消息,尽管将 usesCpuOnly 设置为 true
2019-07-23 12:04:21.747498+0800 Demo[351:9947] Execution of the command buffer was aborted due to an error during execution. Insufficient Permission (to submit GPU work from background) (IOAF code 6)
Error: command buffer exited with error status.
The Metal Performance Shaders operations encoded on it may not have completed.
Error:
(null)
Insufficient Permission (to submit GPU work from background) (IOAF code 6)
<AGXA9FamilyCommandBuffer: 0x106b70720>
label = <none>
device = <AGXA9Device: 0x10bdc4000>
name = Apple A9 GPU
commandQueue = <AGXA9FamilyCommandQueue: 0x106a7f670>
label = <none>
device = <AGXA9Device: 0x10bdc4000>
name = Apple A9 GPU
retainedReferences = 1
2019-07-23 12:04:21.748800+0800 Demo[351:9982] [espresso] [Espresso::handle_ex_plan] exception=Espresso exception: "Generic error": Insufficient Permission (to submit GPU work from background) (IOAF code 6); code=7 status=-1
2019-07-23 12:04:21.749744+0800 Demo[351:9982] [StarMobile] [ERROR] CoreMLClassifier:112 processClassifications(for:error:) error: Unable to classify image. : Optional(Error Domain=com.apple.vis Code=9 "Could not run network (-1: ESPRESSO_STATUS_ERROR_GENERIC)" UserInfo=NSLocalizedDescription=Could not run network (-1: ESPRESSO_STATUS_ERROR_GENERIC))
2019-07-23 12:04:21.750350+0800 Demo[351:9982] [StarMobile] [ERROR] CoreMLClassifier:105 updateClassifications(for:as:) Failed to perform classification.
Could not run network (-1: ESPRESSO_STATUS_ERROR_GENERIC)
请帮忙!
// AppDelegate.swift
func applicationWillResignActive(_ application: UIApplication)
Constants.APP_IS_IN_FOREGROUND = false
func applicationDidBecomeActive(_ application: UIApplication)
Constants.APP_IS_IN_FOREGROUND = true
// Main.swift
class Main()
func run_coreml(imageData: Data)
do
self.usesCpuOnly = Constants.APP_IS_IN_FOREGROUND
let configuration = MLModelConfiguration()
if self.usesCpuOnly
configuration.computeUnits = .cpuOnly
else
configuration.computeUnits = .all
let model = try VNCoreMLModel(for:
CoreMLImageClassifier(configuration: configuration).model)
let request = VNCoreMLRequest(model: model,
completionHandler:
[weak self] request, error in
self?.process(for: request, error: error)
)
request.usesCPUOnly = self.usesCpuOnly
let handler = VNImageRequestHandler(data: imageData)
try handler.perform([request])
catch
// omit implementation
func process()
【问题讨论】:
【参考方案1】:当应用程序进入后台时,您需要创建一个新的VNCoreMLModel
实例并将配置设置为.cpuOnly
,并创建一个新的VNCoreMLRequest
。 Core ML 不会自动从 GPU 切换到 CPU。
【讨论】:
每次运行都在初始化新模型,但还是不行。以上是关于当应用程序进入后台时,应用程序在前台使用带有 GPU 的 CoreML 无法切换到 CPU的主要内容,如果未能解决你的问题,请参考以下文章
当应用程序从后台进入前台时,MPMoviePlayerController 黑屏