From 8dee56c851ce87325f19625b289cad56efd3fdea Mon Sep 17 00:00:00 2001 From: liuruilong Date: Mon, 18 Feb 2019 20:46:48 +0800 Subject: [PATCH] ios metal gpu add multi-output api --- .../MobileNetDemo/MobileNet.swift | 5 +-- .../paddle-mobile-demo/Net/Genet.swift | 4 +-- .../paddle-mobile-demo/Net/MobileNet.swift | 4 +-- .../Net/MobileNetCombined.swift | 4 +-- .../paddle-mobile-demo/Net/MobileNetSSD.swift | 6 ++-- .../Net/MobilenetSSD_AR.swift | 6 ++-- .../paddle-mobile-demo/Net/YoloNet.swift | 4 +-- .../OCInterface/PaddleMobileGPU.h | 6 ++-- .../OCInterface/PaddleMobileGPU.m | 36 ++++++++++++------- .../OCInterface/SuperResolutionNet.swift | 2 +- .../paddle-mobile-demo/ViewController.swift | 7 ++-- .../paddle-mobile/paddle-mobile/API/Net.swift | 13 ++++--- .../paddle-mobile/API/Runner.swift | 6 ++-- .../Src/Framework/Executor.swift | 4 +-- 14 files changed, 63 insertions(+), 44 deletions(-) diff --git a/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift b/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift index 9a50f3db8d..5904af7881 100644 --- a/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift +++ b/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift @@ -42,8 +42,9 @@ public class MobileNet: Net{ let labels = PreWords.init(fileName: "synset") - override public func resultStr(res: ResultHolder) -> String { - let resPointer = res.result + override public func resultStr(res: [ResultHolder]) -> String { + let firstRes = res[0] + let resPointer = firstRes.result var s: [String] = [] (0.. String { - return " \(res.result[0]) ... " + override public func resultStr(res: [ResultHolder]) -> String { + return " \(res[0].result[0]) ... " } } diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNet.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNet.swift index 02fcbefe0b..e15befc6fb 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNet.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNet.swift @@ -43,8 +43,8 @@ public class MobileNet: Net{ let labels = PreWords.init(fileName: "synset") - override public func resultStr(res: ResultHolder) -> String { - let resPointer = res.result + override public func resultStr(res: [ResultHolder]) -> String { + let resPointer = res[0].result var s: [String] = [] (0.. String { - return " \(res.result[0]) ... " + override public func resultStr(res: [ResultHolder]) -> String { + return " \(res[0].result[0]) ... " } } diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetSSD.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetSSD.swift index 280a050781..41d2c82644 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetSSD.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetSSD.swift @@ -45,11 +45,11 @@ public class MobileNet_ssd_hand: Net { } } - override public func resultStr(res: ResultHolder) -> String { - return " \(res)" + override public func resultStr(res: [ResultHolder]) -> String { + return " \(res[0])" } - override public func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder { + override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { // guard let interRes = paddleMobileRes.intermediateResults else { // fatalError(" need have inter result ") diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobilenetSSD_AR.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobilenetSSD_AR.swift index 3080dfb469..60aa3adf07 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobilenetSSD_AR.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobilenetSSD_AR.swift @@ -39,11 +39,11 @@ public class MobileNet_ssd_AR: Net { } } - override public func resultStr(res: ResultHolder) -> String { - return " \(res.result[0])" + override public func resultStr(res: [ResultHolder]) -> String { + return " \(res[0].result[0])" } - override public func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder { + override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { fatalError() // guard let interRes = paddleMobileRes.intermediateResults else { // fatalError(" need have inter result ") diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/YoloNet.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/YoloNet.swift index 5017d3274d..7aeabb0f73 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/YoloNet.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/YoloNet.swift @@ -27,8 +27,8 @@ public class YoloNet: Net { // metalLibPath = Bundle.main.path(forResource: "PaddleMobileMetal", ofType: "metallib") ?! " can't be nil " } - override public func resultStr(res: ResultHolder) -> String { - return " \(res.result[0]) ... " + override public func resultStr(res: [ResultHolder]) -> String { + return " \(res[0].result[0]) ... " } } diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/PaddleMobileGPU.h b/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/PaddleMobileGPU.h index 683ef3272d..cd99ddad43 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/PaddleMobileGPU.h +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/PaddleMobileGPU.h @@ -26,6 +26,8 @@ typedef enum : NSUInteger { @property (assign, nonatomic) int outputSize; +@property (strong, nonatomic) NSArray *dim; + -(void)releaseOutput; @end @@ -88,13 +90,13 @@ typedef enum : NSUInteger { * texture: 需要进行预测的图像转换的 texture * completion: 预测完成回调 */ --(void)predict:(id)texture withCompletion:(void (^)(BOOL, NSArray *))completion; +-(void)predict:(id)texture withCompletion:(void (^)(BOOL, NSArray*> *))completion; /* * texture: 需要进行预测的图像转换的 texture * completion: 预测完成回调 */ --(void)predict:(id)texture withResultCompletion:(void (^)(BOOL, PaddleMobileGPUResult *))completion; +-(void)predict:(id)texture withResultCompletion:(void (^)(BOOL, NSArray *))completion; /* * 清理内存 diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/PaddleMobileGPU.m b/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/PaddleMobileGPU.m index 7625788b53..3a58db2988 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/PaddleMobileGPU.m +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/PaddleMobileGPU.m @@ -66,24 +66,34 @@ return [runner load]; } --(void)predict:(id)texture withCompletion:(void (^)(BOOL, NSArray *))completion { +-(void)predict:(id)texture withCompletion:(void (^)(BOOL, NSArray*> *))completion { - [runner predictWithTexture:texture completion:^(BOOL success, ResultHolder * _Nullable result) { - NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:result.capacity]; - for (int i = 0; i < result.capacity; ++i) { - [resultArray addObject:[NSNumber numberWithFloat:result.result[i]]]; + [runner predictWithTexture:texture completion:^(BOOL success, NSArray * _Nullable resultArr) { + NSMutableArray*> *ocResultArray = [NSMutableArray arrayWithCapacity:resultArr.count]; + for (int i = 0; i < resultArr.count; ++i) { + ResultHolder *resultHolder = resultArr[i]; + NSMutableArray *res = [NSMutableArray arrayWithCapacity:resultHolder.capacity]; + for (int j = 0; j < resultHolder.capacity; ++j) { + [res addObject:[NSNumber numberWithFloat:resultHolder.result[i]]]; + } + [ocResultArray addObject:res]; + [resultHolder releasePointer]; } - completion(success, resultArray); - [result releasePointer]; - + completion(success, ocResultArray); }]; } --(void)predict:(id)texture withResultCompletion:(void (^)(BOOL, PaddleMobileGPUResult *))completion { - [runner predictWithTexture:texture completion:^(BOOL success, ResultHolder * _Nullable result) { - PaddleMobileGPUResult *gpuResult = [[PaddleMobileGPUResult alloc] init]; - [gpuResult setOutputResult:result]; - completion(success, gpuResult); +-(void)predict:(id)texture withResultCompletion:(void (^)(BOOL, NSArray *))completion { + [runner predictWithTexture:texture completion:^(BOOL success, NSArray * _Nullable resultArr) { + NSMutableArray *ocResultArr = [NSMutableArray arrayWithCapacity:resultArr.count]; + for (int i = 0; i < resultArr.count; ++i) { + ResultHolder *result = resultArr[i]; + PaddleMobileGPUResult *gpuResult = [[PaddleMobileGPUResult alloc] init]; + gpuResult.dim = result.dim; + [gpuResult setOutputResult:result]; + [ocResultArr addObject:gpuResult]; + } + completion(success, ocResultArr); }]; } diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/SuperResolutionNet.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/SuperResolutionNet.swift index 284612a04d..8745efaed0 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/SuperResolutionNet.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/OCInterface/SuperResolutionNet.swift @@ -16,7 +16,7 @@ import Foundation import paddle_mobile @objc public class SuperResolutionNet: Net{ - override public func resultStr(res: ResultHolder) -> String { + override public func resultStr(res: [ResultHolder]) -> String { return "未实现" } diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/ViewController.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/ViewController.swift index 5d40da5771..612a986d85 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/ViewController.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/ViewController.swift @@ -147,7 +147,8 @@ class ViewController: UIViewController { fatalError() } - if success, let inResultHolder = resultHolder { + if success, let inResultHolderArr = resultHolder { + let inResultHolder = inResultHolderArr[0] if i == max - 1 { let time = Date.init().timeIntervalSince(startDate) @@ -160,7 +161,7 @@ class ViewController: UIViewController { } DispatchQueue.main.async { - resultHolder?.releasePointer() + resultHolder?.first?.releasePointer() } } } @@ -272,7 +273,7 @@ extension ViewController: VideoCaptureDelegate{ runner.scaleTexture(input: texture) { (scaledTexture) in self.runner.predict(texture: scaledTexture, completion: { (success, resultHolder) in // print(resultHolder!.result![0]) - resultHolder?.releasePointer() + resultHolder?.first?.releasePointer() }) } } diff --git a/metal/paddle-mobile/paddle-mobile/API/Net.swift b/metal/paddle-mobile/paddle-mobile/API/Net.swift index 6eb7732410..cc8a4c6ca2 100644 --- a/metal/paddle-mobile/paddle-mobile/API/Net.swift +++ b/metal/paddle-mobile/paddle-mobile/API/Net.swift @@ -71,17 +71,20 @@ import Foundation super.init() } - @objc open func resultStr(res: ResultHolder) -> String { + @objc open func resultStr(res: [ResultHolder]) -> String { fatalError() } - @objc open func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder { - guard let inResPointer = paddleMobileRes.resultPointer else { - fatalError() + @objc open func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { + return paddleMobileRes.map { (gpuRes) -> ResultHolder in + guard let inResPointer = gpuRes.resultPointer else { + fatalError() + } + return ResultHolder.init(inResult: inResPointer, inCapacity: paddleMobileRes.capacity, inDim: gpuRes.dim) } - return ResultHolder.init(inResult: inResPointer, inCapacity: paddleMobileRes.capacity) } open func updateProgram(program: Program) { } + } diff --git a/metal/paddle-mobile/paddle-mobile/API/Runner.swift b/metal/paddle-mobile/paddle-mobile/API/Runner.swift index b4b7403ec8..2d7bf9d190 100644 --- a/metal/paddle-mobile/paddle-mobile/API/Runner.swift +++ b/metal/paddle-mobile/paddle-mobile/API/Runner.swift @@ -18,10 +18,12 @@ import Foundation @objc public class ResultHolder: NSObject { @objc public let result: UnsafeMutablePointer @objc public let capacity: Int + @objc public let dim: [Int] - init(inResult: UnsafeMutablePointer, inCapacity: Int) { + init(inResult: UnsafeMutablePointer, inCapacity: Int, inDim: [Int]) { result = inResult capacity = inCapacity + dim = inDim } @objc public func releasePointer() { @@ -99,7 +101,7 @@ import Foundation /// - Parameters: /// - texture: 输入 texture 需要使用 getTexture 获得 /// - 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 { try self.executor?.predict(input: texture, dim: self.net.inputDim, completionHandle: { [weak self] (res) in guard let SSelf = self else { diff --git a/metal/paddle-mobile/paddle-mobile/Src/Framework/Executor.swift b/metal/paddle-mobile/paddle-mobile/Src/Framework/Executor.swift index ec29df04e7..8f02bf17bc 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Framework/Executor.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Framework/Executor.swift @@ -69,7 +69,7 @@ public class Executor { } } - 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() guard let buffer = queue.makeCommandBuffer() else { @@ -135,7 +135,7 @@ public class Executor { resultHolder = GPUResultHolder.init(inDim: output.dim.dims, inPointer: output.result, inCapacity: output.capacity) } - completionHandle(resultHolder) + completionHandle([resultHolder]) SSelf.inflightSemaphore.signal() } -- GitLab