未验证 提交 e7328579 编写于 作者: N NazgulLee 提交者: GitHub

fix semaphore crash (#1591)

上级 ceda3f4e
...@@ -43,7 +43,7 @@ import paddle_mobile ...@@ -43,7 +43,7 @@ import paddle_mobile
metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib")
} }
override public func updateProgram(program: Program) { override public func updateProgram(program: Program) throws {
// n h w c // n h w c
for block in program.programDesc.blocks { for block in program.programDesc.blocks {
for varDesc in block.vars { for varDesc in block.vars {
...@@ -54,14 +54,21 @@ import paddle_mobile ...@@ -54,14 +54,21 @@ import paddle_mobile
let newDim = Dim.init(inDim: [texture.dim[0], inputDim[1], inputDim[2], texture.tensorDim[1]]) let newDim = Dim.init(inDim: [texture.dim[0], inputDim[1], inputDim[2], texture.tensorDim[1]])
print(" var desc name " + varDesc.name + " new dim" + "\(newDim)") print(" var desc name " + varDesc.name + " new dim" + "\(newDim)")
texture.updateDims(inTensorDim: Dim.init(inDim: [texture.tensorDim[0], texture.tensorDim[1], inputDim[1], inputDim[2]]), inDim: newDim) do {
texture.initTexture(device: device, inTranspose: [0, 1, 2, 3], computePrecision: GlobalConfig.shared.computePrecision) try texture.updateDims(inTensorDim: Dim.init(inDim: [texture.tensorDim[0], texture.tensorDim[1], inputDim[1], inputDim[2]]), inDim: newDim)
try texture.initTexture(device: device, inTranspose: [0, 1, 2, 3], computePrecision: GlobalConfig.shared.computePrecision)
} catch let error {
throw error
}
let output: FetchHolder = program.scope.output() as! FetchHolder if let output: FetchHolder = program.scope.output() as? FetchHolder {
output.dim = newDim output.dim = newDim
output.capacity = newDim.numel() output.capacity = newDim.numel()
output.paddedCapacity = newDim.numel() * 4 output.paddedCapacity = newDim.numel() * 4
output.initBuffer(device: device) output.initBuffer(device: device)
} else {
throw PaddleMobileError.loaderError(message: "scope output nil")
}
} }
} }
} }
......
...@@ -119,12 +119,15 @@ import Foundation ...@@ -119,12 +119,15 @@ import Foundation
@objc public func predict(texture: MTLTexture, completion: @escaping ( _ success: Bool, _ result: [ResultHolder]?) -> Void) { @objc public func predict(texture: MTLTexture, completion: @escaping ( _ success: Bool, _ result: [ResultHolder]?) -> Void) {
do { do {
try self.executor?.predict(input: texture, dim: self.net.inputDim, completionHandle: { [weak self] (res) in try self.executor?.predict(input: texture, dim: self.net.inputDim, completionHandle: { [weak self] (success, res) in
guard let SSelf = self else { if success, let SSelf = self, let res = res {
fatalError( " self nil " )
}
let result = SSelf.net.fetchResult(paddleMobileRes: res) let result = SSelf.net.fetchResult(paddleMobileRes: res)
if result.count > 0 {
completion(true, result) completion(true, result)
return
}
}
completion(false, nil)
}, preProcessKernle: self.net.preprocessKernel, except: self.net.except) }, preProcessKernle: self.net.preprocessKernel, except: self.net.except)
} catch let error { } catch let error {
print(error) print(error)
......
...@@ -42,7 +42,7 @@ var isTest = false ...@@ -42,7 +42,7 @@ var isTest = false
} }
protocol Executorable { protocol Executorable {
func predict(input: MTLTexture, dim: Dim, completionHandle: @escaping ([GPUResultHolder]) -> Void, preProcessKernle: CusomKernel?, except: Int) throws func predict(input: MTLTexture, dim: Dim, completionHandle: @escaping ( _ success: Bool, _ result: [GPUResultHolder]?) -> Void, preProcessKernle: CusomKernel?, except: Int) throws
func clear() func clear()
} }
...@@ -53,6 +53,8 @@ public class Executor<P: PrecisionProtocol>: Executorable{ ...@@ -53,6 +53,8 @@ public class Executor<P: PrecisionProtocol>: Executorable{
let device: MTLDevice let device: MTLDevice
let inflightSemaphore: DispatchSemaphore let inflightSemaphore: DispatchSemaphore
let queue: MTLCommandQueue let queue: MTLCommandQueue
private var isValid = true
init(inDevice:MTLDevice, inQueue: MTLCommandQueue, inProgram: Program, initContext: InitContext) throws { init(inDevice:MTLDevice, inQueue: MTLCommandQueue, inProgram: Program, initContext: InitContext) throws {
self.inflightSemaphore = DispatchSemaphore(value: 1) self.inflightSemaphore = DispatchSemaphore(value: 1)
program = inProgram program = inProgram
...@@ -73,9 +75,11 @@ public class Executor<P: PrecisionProtocol>: Executorable{ ...@@ -73,9 +75,11 @@ public class Executor<P: PrecisionProtocol>: Executorable{
} }
} }
public func predict(input: MTLTexture, dim: Dim, completionHandle: @escaping ([GPUResultHolder]) -> Void, preProcessKernle: CusomKernel? = nil, except: Int = 0) throws { public func predict(input: MTLTexture, dim: Dim, completionHandle: @escaping ( _ success: Bool, _ result: [GPUResultHolder]?) -> Void, preProcessKernle: CusomKernel? = nil, except: Int = 0) throws {
inflightSemaphore.wait() inflightSemaphore.wait()
guard isValid else {
throw PaddleMobileError.predictError(message: "Executor is cleared and invalid")
}
guard let buffer = queue.makeCommandBuffer() else { guard let buffer = queue.makeCommandBuffer() else {
throw PaddleMobileError.predictError(message: "CommandBuffer is nil") throw PaddleMobileError.predictError(message: "CommandBuffer is nil")
} }
...@@ -110,9 +114,20 @@ public class Executor<P: PrecisionProtocol>: Executorable{ ...@@ -110,9 +114,20 @@ public class Executor<P: PrecisionProtocol>: Executorable{
outputTextures = ops[ops.count - except].inputVariant() outputTextures = ops[ops.count - except].inputVariant()
} }
let safeComplete = { [weak self] (success: Bool, result: [GPUResultHolder]?) in
completionHandle(success, result)
self?.inflightSemaphore.signal()
}
buffer.addCompletedHandler { [weak self] (commandbuffer) in buffer.addCompletedHandler { [weak self] (commandbuffer) in
guard let SSelf = self else { guard let SSelf = self else {
fatalError() safeComplete(false, nil)
return
}
guard SSelf.isValid else {
safeComplete(false, nil)
return
} }
//将输入写进文件 //将输入写进文件
...@@ -133,24 +148,31 @@ public class Executor<P: PrecisionProtocol>: Executorable{ ...@@ -133,24 +148,31 @@ public class Executor<P: PrecisionProtocol>: Executorable{
} }
} }
var resultHolder: GPUResultHolder var resultHolder: GPUResultHolder?
if except > 0 { if except > 0 {
resultHolder = GPUResultHolder.init(inDim: [], inPointer: nil, inCapacity: 0, inIntermediateResults: outputTextures) resultHolder = GPUResultHolder.init(inDim: [], inPointer: nil, inCapacity: 0, inIntermediateResults: outputTextures)
} else { } else if let output = SSelf.program.scope.output() as? FetchHolder {
let outputVar: Variant = SSelf.program.scope.output()!
let output: FetchHolder = outputVar as! FetchHolder
resultHolder = GPUResultHolder.init(inDim: output.dim.dims, inPointer: output.result, inCapacity: output.capacity) resultHolder = GPUResultHolder.init(inDim: output.dim.dims, inPointer: output.result, inCapacity: output.capacity)
} }
if let resultHolder = resultHolder {
completionHandle([resultHolder]) safeComplete(true, [resultHolder])
SSelf.inflightSemaphore.signal() } else {
safeComplete(false, nil)
}
} }
buffer.commit() buffer.commit()
} }
public func clear() { public func clear() {
isValid = false
program.scope.clear() program.scope.clear()
} }
deinit {
while (inflightSemaphore.signal() != 0) {
}
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册