提交 8dee56c8 编写于 作者: L liuruilong

ios metal gpu add multi-output api

上级 3a8d22a4
...@@ -42,8 +42,9 @@ public class MobileNet: Net{ ...@@ -42,8 +42,9 @@ public class MobileNet: Net{
let labels = PreWords.init(fileName: "synset") let labels = PreWords.init(fileName: "synset")
override public func resultStr(res: ResultHolder) -> String { override public func resultStr(res: [ResultHolder]) -> String {
let resPointer = res.result let firstRes = res[0]
let resPointer = firstRes.result
var s: [String] = [] var s: [String] = []
(0..<res.capacity).map { resPointer[$0] }.top(r: 5).enumerated().forEach{ (0..<res.capacity).map { resPointer[$0] }.top(r: 5).enumerated().forEach{
s.append(String(format: "%d: %@ (%3.2f%%)", $0 + 1, labels[$1.0], $1.1 * 100)) s.append(String(format: "%d: %@ (%3.2f%%)", $0 + 1, labels[$1.0], $1.1 * 100))
......
...@@ -41,8 +41,8 @@ public class Genet: Net { ...@@ -41,8 +41,8 @@ public class Genet: Net {
} }
} }
override public func resultStr(res: ResultHolder) -> String { override public func resultStr(res: [ResultHolder]) -> String {
return " \(res.result[0]) ... " return " \(res[0].result[0]) ... "
} }
} }
...@@ -43,8 +43,8 @@ public class MobileNet: Net{ ...@@ -43,8 +43,8 @@ public class MobileNet: Net{
let labels = PreWords.init(fileName: "synset") let labels = PreWords.init(fileName: "synset")
override public func resultStr(res: ResultHolder) -> String { override public func resultStr(res: [ResultHolder]) -> String {
let resPointer = res.result let resPointer = res[0].result
var s: [String] = [] var s: [String] = []
(0..<res.capacity).map { resPointer[$0] }.top(r: 5).enumerated().forEach{ (0..<res.capacity).map { resPointer[$0] }.top(r: 5).enumerated().forEach{
s.append(String(format: "%d: %@ (%3.2f%%)", $0 + 1, labels[$1.0], $1.1 * 100)) s.append(String(format: "%d: %@ (%3.2f%%)", $0 + 1, labels[$1.0], $1.1 * 100))
......
...@@ -26,8 +26,8 @@ public class MobileNetCombined: Net { ...@@ -26,8 +26,8 @@ public class MobileNetCombined: Net {
// metalLibPath = Bundle.main.path(forResource: "PaddleMobileMetal", ofType: "metallib") ?! " can't be nil " // metalLibPath = Bundle.main.path(forResource: "PaddleMobileMetal", ofType: "metallib") ?! " can't be nil "
} }
override public func resultStr(res: ResultHolder) -> String { override public func resultStr(res: [ResultHolder]) -> String {
return " \(res.result[0]) ... " return " \(res[0].result[0]) ... "
} }
} }
...@@ -45,11 +45,11 @@ public class MobileNet_ssd_hand: Net { ...@@ -45,11 +45,11 @@ public class MobileNet_ssd_hand: Net {
} }
} }
override public func resultStr(res: ResultHolder) -> String { override public func resultStr(res: [ResultHolder]) -> String {
return " \(res)" return " \(res[0])"
} }
override public func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder { override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] {
// guard let interRes = paddleMobileRes.intermediateResults else { // guard let interRes = paddleMobileRes.intermediateResults else {
// fatalError(" need have inter result ") // fatalError(" need have inter result ")
......
...@@ -39,11 +39,11 @@ public class MobileNet_ssd_AR: Net { ...@@ -39,11 +39,11 @@ public class MobileNet_ssd_AR: Net {
} }
} }
override public func resultStr(res: ResultHolder) -> String { override public func resultStr(res: [ResultHolder]) -> String {
return " \(res.result[0])" return " \(res[0].result[0])"
} }
override public func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder { override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] {
fatalError() fatalError()
// guard let interRes = paddleMobileRes.intermediateResults else { // guard let interRes = paddleMobileRes.intermediateResults else {
// fatalError(" need have inter result ") // fatalError(" need have inter result ")
......
...@@ -27,8 +27,8 @@ public class YoloNet: Net { ...@@ -27,8 +27,8 @@ public class YoloNet: Net {
// metalLibPath = Bundle.main.path(forResource: "PaddleMobileMetal", ofType: "metallib") ?! " can't be nil " // metalLibPath = Bundle.main.path(forResource: "PaddleMobileMetal", ofType: "metallib") ?! " can't be nil "
} }
override public func resultStr(res: ResultHolder) -> String { override public func resultStr(res: [ResultHolder]) -> String {
return " \(res.result[0]) ... " return " \(res[0].result[0]) ... "
} }
} }
...@@ -26,6 +26,8 @@ typedef enum : NSUInteger { ...@@ -26,6 +26,8 @@ typedef enum : NSUInteger {
@property (assign, nonatomic) int outputSize; @property (assign, nonatomic) int outputSize;
@property (strong, nonatomic) NSArray <NSNumber *>*dim;
-(void)releaseOutput; -(void)releaseOutput;
@end @end
...@@ -88,13 +90,13 @@ typedef enum : NSUInteger { ...@@ -88,13 +90,13 @@ typedef enum : NSUInteger {
* texture: 需要进行预测的图像转换的 texture * texture: 需要进行预测的图像转换的 texture
* completion: 预测完成回调 * completion: 预测完成回调
*/ */
-(void)predict:(id<MTLTexture>)texture withCompletion:(void (^)(BOOL, NSArray<NSNumber *> *))completion; -(void)predict:(id<MTLTexture>)texture withCompletion:(void (^)(BOOL, NSArray<NSArray <NSNumber *>*> *))completion;
/* /*
* texture: 需要进行预测的图像转换的 texture * texture: 需要进行预测的图像转换的 texture
* completion: 预测完成回调 * completion: 预测完成回调
*/ */
-(void)predict:(id<MTLTexture>)texture withResultCompletion:(void (^)(BOOL, PaddleMobileGPUResult *))completion; -(void)predict:(id<MTLTexture>)texture withResultCompletion:(void (^)(BOOL, NSArray <PaddleMobileGPUResult *> *))completion;
/* /*
* 清理内存 * 清理内存
......
...@@ -66,24 +66,34 @@ ...@@ -66,24 +66,34 @@
return [runner load]; return [runner load];
} }
-(void)predict:(id<MTLTexture>)texture withCompletion:(void (^)(BOOL, NSArray<NSNumber *> *))completion { -(void)predict:(id<MTLTexture>)texture withCompletion:(void (^)(BOOL, NSArray<NSArray <NSNumber *>*> *))completion {
[runner predictWithTexture:texture completion:^(BOOL success, ResultHolder * _Nullable result) { [runner predictWithTexture:texture completion:^(BOOL success, NSArray<ResultHolder *> * _Nullable resultArr) {
NSMutableArray<NSNumber *> *resultArray = [NSMutableArray arrayWithCapacity:result.capacity]; NSMutableArray<NSMutableArray <NSNumber *>*> *ocResultArray = [NSMutableArray arrayWithCapacity:resultArr.count];
for (int i = 0; i < result.capacity; ++i) { for (int i = 0; i < resultArr.count; ++i) {
[resultArray addObject:[NSNumber numberWithFloat:result.result[i]]]; ResultHolder *resultHolder = resultArr[i];
NSMutableArray <NSNumber *>*res = [NSMutableArray arrayWithCapacity:resultHolder.capacity];
for (int j = 0; j < resultHolder.capacity; ++j) {
[res addObject:[NSNumber numberWithFloat:resultHolder.result[i]]];
} }
completion(success, resultArray); [ocResultArray addObject:res];
[result releasePointer]; [resultHolder releasePointer];
}
completion(success, ocResultArray);
}]; }];
} }
-(void)predict:(id<MTLTexture>)texture withResultCompletion:(void (^)(BOOL, PaddleMobileGPUResult *))completion { -(void)predict:(id<MTLTexture>)texture withResultCompletion:(void (^)(BOOL, NSArray <PaddleMobileGPUResult *> *))completion {
[runner predictWithTexture:texture completion:^(BOOL success, ResultHolder * _Nullable result) { [runner predictWithTexture:texture completion:^(BOOL success, NSArray<ResultHolder *> * _Nullable resultArr) {
NSMutableArray <PaddleMobileGPUResult *> *ocResultArr = [NSMutableArray arrayWithCapacity:resultArr.count];
for (int i = 0; i < resultArr.count; ++i) {
ResultHolder *result = resultArr[i];
PaddleMobileGPUResult *gpuResult = [[PaddleMobileGPUResult alloc] init]; PaddleMobileGPUResult *gpuResult = [[PaddleMobileGPUResult alloc] init];
gpuResult.dim = result.dim;
[gpuResult setOutputResult:result]; [gpuResult setOutputResult:result];
completion(success, gpuResult); [ocResultArr addObject:gpuResult];
}
completion(success, ocResultArr);
}]; }];
} }
......
...@@ -16,7 +16,7 @@ import Foundation ...@@ -16,7 +16,7 @@ import Foundation
import paddle_mobile import paddle_mobile
@objc public class SuperResolutionNet: Net{ @objc public class SuperResolutionNet: Net{
override public func resultStr(res: ResultHolder) -> String { override public func resultStr(res: [ResultHolder]) -> String {
return "未实现" return "未实现"
} }
......
...@@ -147,7 +147,8 @@ class ViewController: UIViewController { ...@@ -147,7 +147,8 @@ class ViewController: UIViewController {
fatalError() fatalError()
} }
if success, let inResultHolder = resultHolder { if success, let inResultHolderArr = resultHolder {
let inResultHolder = inResultHolderArr[0]
if i == max - 1 { if i == max - 1 {
let time = Date.init().timeIntervalSince(startDate) let time = Date.init().timeIntervalSince(startDate)
...@@ -160,7 +161,7 @@ class ViewController: UIViewController { ...@@ -160,7 +161,7 @@ class ViewController: UIViewController {
} }
DispatchQueue.main.async { DispatchQueue.main.async {
resultHolder?.releasePointer() resultHolder?.first?.releasePointer()
} }
} }
} }
...@@ -272,7 +273,7 @@ extension ViewController: VideoCaptureDelegate{ ...@@ -272,7 +273,7 @@ extension ViewController: VideoCaptureDelegate{
runner.scaleTexture(input: texture) { (scaledTexture) in runner.scaleTexture(input: texture) { (scaledTexture) in
self.runner.predict(texture: scaledTexture, completion: { (success, resultHolder) in self.runner.predict(texture: scaledTexture, completion: { (success, resultHolder) in
// print(resultHolder!.result![0]) // print(resultHolder!.result![0])
resultHolder?.releasePointer() resultHolder?.first?.releasePointer()
}) })
} }
} }
......
...@@ -71,17 +71,20 @@ import Foundation ...@@ -71,17 +71,20 @@ import Foundation
super.init() super.init()
} }
@objc open func resultStr(res: ResultHolder) -> String { @objc open func resultStr(res: [ResultHolder]) -> String {
fatalError() fatalError()
} }
@objc open func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder { @objc open func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] {
guard let inResPointer = paddleMobileRes.resultPointer else { return paddleMobileRes.map { (gpuRes) -> ResultHolder in
guard let inResPointer = gpuRes.resultPointer else {
fatalError() fatalError()
} }
return ResultHolder.init(inResult: inResPointer, inCapacity: paddleMobileRes.capacity) return ResultHolder.init(inResult: inResPointer, inCapacity: paddleMobileRes.capacity, inDim: gpuRes.dim)
}
} }
open func updateProgram(program: Program) { open func updateProgram(program: Program) {
} }
} }
...@@ -18,10 +18,12 @@ import Foundation ...@@ -18,10 +18,12 @@ import Foundation
@objc public class ResultHolder: NSObject { @objc public class ResultHolder: NSObject {
@objc public let result: UnsafeMutablePointer<Float32> @objc public let result: UnsafeMutablePointer<Float32>
@objc public let capacity: Int @objc public let capacity: Int
@objc public let dim: [Int]
init(inResult: UnsafeMutablePointer<Float32>, inCapacity: Int) { init(inResult: UnsafeMutablePointer<Float32>, inCapacity: Int, inDim: [Int]) {
result = inResult result = inResult
capacity = inCapacity capacity = inCapacity
dim = inDim
} }
@objc public func releasePointer() { @objc public func releasePointer() {
...@@ -99,7 +101,7 @@ import Foundation ...@@ -99,7 +101,7 @@ import Foundation
/// - Parameters: /// - Parameters:
/// - texture: 输入 texture 需要使用 getTexture 获得 /// - texture: 输入 texture 需要使用 getTexture 获得
/// - completion: 结果回调, 当 success 为 true 时 result 不为 nil /// - completion: 结果回调, 当 success 为 true 时 result 不为 nil
@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] (res) in
guard let SSelf = self else { guard let SSelf = self else {
......
...@@ -69,7 +69,7 @@ public class Executor<P: PrecisionType> { ...@@ -69,7 +69,7 @@ public class Executor<P: PrecisionType> {
} }
} }
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 ([GPUResultHolder]) -> Void, preProcessKernle: CusomKernel? = nil, except: Int = 0) throws {
inflightSemaphore.wait() inflightSemaphore.wait()
guard let buffer = queue.makeCommandBuffer() else { guard let buffer = queue.makeCommandBuffer() else {
...@@ -135,7 +135,7 @@ public class Executor<P: PrecisionType> { ...@@ -135,7 +135,7 @@ public class Executor<P: PrecisionType> {
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)
} }
completionHandle(resultHolder) completionHandle([resultHolder])
SSelf.inflightSemaphore.signal() SSelf.inflightSemaphore.signal()
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册