当应用程序进入后台时,应用程序在前台使用带有 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 黑屏

当应用程序进入后台时,在前台执行的长时间运行的任务被挂起

应用程序将进入后台并进入前台遇到黑屏

Android需要事件前台和后台

当 iphone 应用程序进入后台或前台状态时,如何保存数据?

当应用程序从后台进入前台时,onBackPress() 不起作用