Reputation: 31
I am working with Swift to implement CoreML in an iOS app. When in foreground, I want CoreML to use GPU for performance enhancement, however when switch to background, CoreML should use CPU because by iOS, GPU is not able to run in background.
However, during background, GPU is throwing permission error saying that there is no permission to use GPU in the background. But in the code i have already registered CoreML to use CPU only whenever the app is in the background, but it seems like the CoreML class is not reading the parameter.
Error message obtained when CoreML is running in background, despite setting usesCpuOnly to 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)
Please help!
// 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() {}
}
Upvotes: 1
Views: 1691
Reputation: 7892
When the app goes into the background, you will need to create a new VNCoreMLModel
instance with the configuration set to .cpuOnly
, and make a new VNCoreMLRequest
. Core ML doesn't automagically switch from GPU to CPU.
Upvotes: 1