diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo.xcodeproj/project.pbxproj b/metal/paddle-mobile-demo/paddle-mobile-demo.xcodeproj/project.pbxproj index 6d057200279c3d2472c764587e5a93dd0352526e..aa98fce5d07f4eb231303816d7165b9e95d7050c 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo.xcodeproj/project.pbxproj +++ b/metal/paddle-mobile-demo/paddle-mobile-demo.xcodeproj/project.pbxproj @@ -14,6 +14,9 @@ FC039B8720E11C550081E9F8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8520E11C550081E9F8 /* Main.storyboard */; }; FC039B8920E11C560081E9F8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8820E11C560081E9F8 /* Assets.xcassets */; }; FC039B8C20E11C560081E9F8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8A20E11C560081E9F8 /* LaunchScreen.storyboard */; }; + FC27991021341CE5000B6BAD /* Net.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC27990F21341CE5000B6BAD /* Net.swift */; }; + FC3C800F2133F46600D1295E /* MobileNetSSD.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC3C800E2133F46600D1295E /* MobileNetSSD.swift */; }; + FC3C80112133F4AB00D1295E /* MobileNet.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC3C80102133F4AB00D1295E /* MobileNet.swift */; }; FC918191211DBC3500B6F354 /* paddle-mobile.png in Resources */ = {isa = PBXBuildFile; fileRef = FC918190211DBC3500B6F354 /* paddle-mobile.png */; }; FC918193211DC70500B6F354 /* iphone.JPG in Resources */ = {isa = PBXBuildFile; fileRef = FC918192211DC70500B6F354 /* iphone.JPG */; }; FCA3A16121313E1F00084FE5 /* hand.jpg in Resources */ = {isa = PBXBuildFile; fileRef = FCA3A16021313E1F00084FE5 /* hand.jpg */; }; @@ -22,7 +25,6 @@ FCBCCC552122EF5500D94F7E /* MetalHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCBCCC542122EF5400D94F7E /* MetalHelper.swift */; }; FCD04E6320F3146B0007374F /* params in Resources */ = {isa = PBXBuildFile; fileRef = FCD04E6120F3146A0007374F /* params */; }; FCD04E6420F3146B0007374F /* model in Resources */ = {isa = PBXBuildFile; fileRef = FCD04E6220F3146A0007374F /* model */; }; - FCDFD3FB211D72C3005AB38B /* ModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCDFD3FA211D72C3005AB38B /* ModelHelper.swift */; }; FCDFD41B211D91C7005AB38B /* synset.txt in Resources */ = {isa = PBXBuildFile; fileRef = FCDFD41A211D91C7005AB38B /* synset.txt */; }; FCEBEC2C20E1391F00C0B14D /* paddle_mobile.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */; }; FCEBEC2D20E1391F00C0B14D /* paddle_mobile.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -55,6 +57,9 @@ FC039B8820E11C560081E9F8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; FC039B8B20E11C560081E9F8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; FC039B8D20E11C560081E9F8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FC27990F21341CE5000B6BAD /* Net.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Net.swift; sourceTree = ""; }; + FC3C800E2133F46600D1295E /* MobileNetSSD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileNetSSD.swift; sourceTree = ""; }; + FC3C80102133F4AB00D1295E /* MobileNet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileNet.swift; sourceTree = ""; }; FC918190211DBC3500B6F354 /* paddle-mobile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "paddle-mobile.png"; sourceTree = ""; }; FC918192211DC70500B6F354 /* iphone.JPG */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = iphone.JPG; sourceTree = ""; }; FCA3A16021313E1F00084FE5 /* hand.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hand.jpg; sourceTree = ""; }; @@ -63,7 +68,6 @@ FCBCCC542122EF5400D94F7E /* MetalHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalHelper.swift; sourceTree = ""; }; FCD04E6120F3146A0007374F /* params */ = {isa = PBXFileReference; lastKnownFileType = file; path = params; sourceTree = ""; }; FCD04E6220F3146A0007374F /* model */ = {isa = PBXFileReference; lastKnownFileType = file; path = model; sourceTree = ""; }; - FCDFD3FA211D72C3005AB38B /* ModelHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelHelper.swift; sourceTree = ""; }; FCDFD41A211D91C7005AB38B /* synset.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = synset.txt; sourceTree = ""; }; FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = paddle_mobile.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FCEEE7D3210627A000444BEC /* banana.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = banana.jpeg; sourceTree = ""; }; @@ -131,7 +135,9 @@ FC039B8A20E11C560081E9F8 /* LaunchScreen.storyboard */, FC039B8D20E11C560081E9F8 /* Info.plist */, FCBCCC542122EF5400D94F7E /* MetalHelper.swift */, - FCDFD3FA211D72C3005AB38B /* ModelHelper.swift */, + FC3C800E2133F46600D1295E /* MobileNetSSD.swift */, + FC3C80102133F4AB00D1295E /* MobileNet.swift */, + FC27990F21341CE5000B6BAD /* Net.swift */, ); path = "paddle-mobile-demo"; sourceTree = ""; @@ -300,9 +306,11 @@ buildActionMask = 2147483647; files = ( FC039B8420E11C550081E9F8 /* ViewController.swift in Sources */, - FCDFD3FB211D72C3005AB38B /* ModelHelper.swift in Sources */, FC013928210204A3008100E3 /* PreProcessKernel.metal in Sources */, + FC27991021341CE5000B6BAD /* Net.swift in Sources */, FCBCCC552122EF5500D94F7E /* MetalHelper.swift in Sources */, + FC3C80112133F4AB00D1295E /* MobileNet.swift in Sources */, + FC3C800F2133F46600D1295E /* MobileNetSSD.swift in Sources */, FC039B8220E11C550081E9F8 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/MobileNet.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/MobileNet.swift new file mode 100644 index 0000000000000000000000000000000000000000..5b2faac0d6056f29e062f854a21b6e759261118d --- /dev/null +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/MobileNet.swift @@ -0,0 +1,73 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ + +import Foundation +import paddle_mobile + +class MobileNet: Net{ + + var program: Program? + + var executor: Executor? + + let except: Int = 0 + + class MobilenetPreProccess: CusomKernel { + init(device: MTLDevice) { + let s = CusomKernel.Shape.init(inWidth: 224, inHeight: 224, inChannel: 3) + super.init(device: device, inFunctionName: "preprocess", outputDim: s, usePaddleMobileLib: false) + } + } + + class PreWords { + var contents: [String] = [] + init(fileName: String, type: String = "txt", inBundle: Bundle = Bundle.main) { + if let filePath = inBundle.path(forResource: fileName, ofType: type) { + let string = try! String.init(contentsOfFile: filePath) + contents = string.components(separatedBy: CharacterSet.newlines).filter{$0.count > 10}.map{ + String($0[$0.index($0.startIndex, offsetBy: 10)...]) + } + }else{ + fatalError("no file call \(fileName)") + } + } + subscript(index: Int) -> String { + return contents[index] + } + } + + let labels = PreWords.init(fileName: "synset") + + func resultStr(res: [Float]) -> String { + var s: [String] = [] + res.top(r: 5).enumerated().forEach{ + s.append(String(format: "%d: %@ (%3.2f%%)", $0 + 1, labels[$1.0], $1.1 * 100)) + } + return s.joined(separator: "\n") + } + + var preprocessKernel: CusomKernel + let dim = [1, 224, 224, 3] + let modelPath: String + let paramPath: String + let modelDir: String + + init() { + modelPath = Bundle.main.path(forResource: "model", ofType: nil) ?! "model null" + paramPath = Bundle.main.path(forResource: "params", ofType: nil) ?! "para null" + modelDir = "" + preprocessKernel = MobilenetPreProccess.init(device: MetalHelper.shared.device) + } +} + diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/ModelHelper.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/MobileNetSSD.swift similarity index 53% rename from metal/paddle-mobile-demo/paddle-mobile-demo/ModelHelper.swift rename to metal/paddle-mobile-demo/paddle-mobile-demo/MobileNetSSD.swift index 6ff4bbe8e58e2b245e581b7519bc6fc86cfee8cf..820ce88d441bbe5754a7d3c6d197369c14f498f8 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/ModelHelper.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/MobileNetSSD.swift @@ -1,101 +1,27 @@ -// -// ModelHelper.swift -// paddle-mobile-demo -// -// Created by liuRuiLong on 2018/8/10. -// Copyright © 2018年 orange. All rights reserved. -// +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ -import UIKit -import MetalKit import Foundation import paddle_mobile -import MetalPerformanceShaders -let modelHelperMap: [SupportModel : Net] = [.mobilenet : MobileNet.init(), .mobilenet_ssd : MobileNet_ssd_hand.init()] - -enum SupportModel: String{ - case mobilenet = "mobilenet" - case mobilenet_ssd = "mobilenetssd" - static func supportedModels() -> [SupportModel] { - return [.mobilenet, .mobilenet_ssd] - } -} - -protocol Net { - var dim: [Int] { get } - var modelPath: String { get } - var paramPath: String { get } - var modelDir: String { get } - var preprocessKernel: CusomKernel { get } - func getTexture(image: CGImage, getTexture: @escaping (MTLTexture) -> Void) - func resultStr(res: [Float]) -> String - func fetchResult(paddleMobileRes: ResultHolder) -> [Float32] -} - -extension Net { - func getTexture(image: CGImage, getTexture: @escaping (MTLTexture) -> Void) { - let texture = try? MetalHelper.shared.textureLoader.newTexture(cgImage: image, options: [:]) ?! " texture loader error" - MetalHelper.scaleTexture(queue: MetalHelper.shared.queue, input: texture!, size: (224, 224)) { (resTexture) in - getTexture(resTexture) - } - } +class MobileNet_ssd_hand: Net{ - func fetchResult(paddleMobileRes: ResultHolder) -> [Float32] { - return paddleMobileRes.resultArr - } -} - -struct MobileNet: Net{ - class MobilenetPreProccess: CusomKernel { - init(device: MTLDevice) { - let s = CusomKernel.Shape.init(inWidth: 224, inHeight: 224, inChannel: 3) - super.init(device: device, inFunctionName: "preprocess", outputDim: s, usePaddleMobileLib: false) - } - } + var program: Program? - class PreWords { - var contents: [String] = [] - init(fileName: String, type: String = "txt", inBundle: Bundle = Bundle.main) { - if let filePath = inBundle.path(forResource: fileName, ofType: type) { - let string = try! String.init(contentsOfFile: filePath) - contents = string.components(separatedBy: CharacterSet.newlines).filter{$0.count > 10}.map{ - String($0[$0.index($0.startIndex, offsetBy: 10)...]) - } - }else{ - fatalError("no file call \(fileName)") - } - } - subscript(index: Int) -> String { - return contents[index] - } - } - - let labels = PreWords.init(fileName: "synset") - - func resultStr(res: [Float]) -> String { - var s: [String] = [] - res.top(r: 5).enumerated().forEach{ - s.append(String(format: "%d: %@ (%3.2f%%)", $0 + 1, labels[$1.0], $1.1 * 100)) - } - return s.joined(separator: "\n") - } - - var preprocessKernel: CusomKernel - let dim = [1, 224, 224, 3] - let modelPath: String - let paramPath: String - let modelDir: String + var executor: Executor? - init() { - modelPath = Bundle.main.path(forResource: "model", ofType: nil) ?! "model null" - paramPath = Bundle.main.path(forResource: "params", ofType: nil) ?! "para null" - modelDir = "" - preprocessKernel = MobilenetPreProccess.init(device: MetalHelper.shared.device) - } -} - -struct MobileNet_ssd_hand: Net{ + let except: Int = 2 class MobilenetssdPreProccess: CusomKernel { init(device: MTLDevice) { let s = CusomKernel.Shape.init(inWidth: 300, inHeight: 300, inChannel: 3) @@ -105,7 +31,6 @@ struct MobileNet_ssd_hand: Net{ func resultStr(res: [Float]) -> String { return "哈哈哈, 还没好" -// fatalError() } func bboxArea(box: [Float32], normalized: Bool) -> Float32 { @@ -141,10 +66,18 @@ struct MobileNet_ssd_hand: Net{ } func fetchResult(paddleMobileRes: ResultHolder) -> [Float32]{ - let scores = paddleMobileRes.intermediateResults![0] as! Texture - let bbox = paddleMobileRes.intermediateResults![1] as! Texture -// let bbox = paddleMobileRes["box_coder_0.tmp_0"] ?! " no bbox " -// let scores = paddleMobileRes["transpose_12.tmp_0"] ?! " no scores " + guard let interRes = paddleMobileRes.intermediateResults else { + fatalError(" need have inter result ") + } + + guard let scores = interRes["Scores"], scores.count > 0, let score = scores[0] as? Texture else { + fatalError(" need score ") + } + + guard let bboxs = interRes["BBoxes"], bboxs.count > 0, let bbox = bboxs[0] as? Texture else { + fatalError() + } + let score_thredshold: Float32 = 0.01 let nms_top_k = 400 let keep_top_k = 200 @@ -155,43 +88,14 @@ struct MobileNet_ssd_hand: Net{ return f } - let scoresArr = scores.metalTexture.floatArray { (f) -> Float32 in - return f - } - - var scoreFormatArr: [Float32] = [] + let scoreFormatArr: [Float32] = score.metalTexture.realNHWC(dim: (n: score.originDim[0], h: score.originDim[1], w: score.originDim[2], c: score.originDim[3])) var outputArr: [Float32] = [] - - let numOfOneC = (scores.tensorDim[2] + 3) / 4 // 480 - - let cNumOfOneClass = scores.tensorDim[2] // 1917 - - let cPaddedNumOfOneClass = numOfOneC * 4 // 1920 - + let cNumOfOneClass = score.tensorDim[2] // 1917 let boxSize = bbox.tensorDim[2] // 4 - let classNum = scores.tensorDim[1] // 7 - let classNumOneTexture = classNum * 4 // 28 - - for c in 0..(scoreFormatArr[(i * cNumOfOneClass)..<((i + 1) * cNumOfOneClass)]) @@ -249,7 +153,7 @@ struct MobileNet_ssd_hand: Net{ } scoreIndexPairs.sort { $0.0 > $1.0 } - + if scoreIndexPairs.count > keep_top_k { scoreIndexPairs.removeLast(scoreIndexPairs.count - keep_top_k) } @@ -259,9 +163,9 @@ struct MobileNet_ssd_hand: Net{ // label: scoreIndexPair.1.0 let label = scoreIndexPair.1.0 if newIndices[label] != nil { - newIndices[label]?.append((scoreIndexPair.1.0, scoreIndexPair.0)) + newIndices[label]?.append((scoreIndexPair.1.1, scoreIndexPair.0)) } else { - newIndices[label] = [(scoreIndexPair.1.0, scoreIndexPair.0)] + newIndices[label] = [(scoreIndexPair.1.1, scoreIndexPair.0)] } } @@ -275,7 +179,6 @@ struct MobileNet_ssd_hand: Net{ } } print(" fuck success !") - print(outputArr) return outputArr } @@ -292,4 +195,3 @@ struct MobileNet_ssd_hand: Net{ preprocessKernel = MobilenetssdPreProccess.init(device: MetalHelper.shared.device) } } - diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/Net.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/Net.swift new file mode 100644 index 0000000000000000000000000000000000000000..2112af94437a147282fb8f84a2b438da4c5ff039 --- /dev/null +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net.swift @@ -0,0 +1,86 @@ +// +// Net.swift +// paddle-mobile-demo +// +// Created by liuRuiLong on 2018/8/27. +// Copyright © 2018年 orange. All rights reserved. +// + +import Foundation + +import UIKit +import MetalKit +import Foundation +import paddle_mobile +import MetalPerformanceShaders + +let modelHelperMap: [SupportModel : Net] = [.mobilenet : MobileNet.init(), .mobilenet_ssd : MobileNet_ssd_hand.init()] + +enum SupportModel: String{ + case mobilenet = "mobilenet" + case mobilenet_ssd = "mobilenetssd" + static func supportedModels() -> [SupportModel] { + return [.mobilenet, .mobilenet_ssd] + } +} + +protocol Net { + var program: Program? { get set } + var executor: Executor? { get set } + var except: Int { get } + var dim: [Int] { get } + var modelPath: String { get } + var paramPath: String { get } + var modelDir: String { get } + var preprocessKernel: CusomKernel { get } + func getTexture(image: CGImage, getTexture: @escaping (MTLTexture) -> Void) + func resultStr(res: [Float]) -> String + func fetchResult(paddleMobileRes: ResultHolder) -> [Float32] + mutating func load() throws + func predict(inTexture: MTLTexture, completion: @escaping ([Float32]) -> Void) throws + mutating func clear() +} + +extension Net { + + mutating func load() throws { + let queue = MetalHelper.shared.queue + let loader = Loader.init() + do { + program = try loader.load(device: MetalHelper.shared.device, modelPath: modelPath, paraPath: paramPath) + executor = try Executor.init(inDevice: MetalHelper.shared.device, inQueue: queue, inProgram: program!) + } catch let error { + throw error + } + } + + func predict(inTexture: MTLTexture, completion: @escaping ([Float32]) -> Void) throws { + guard let inExecutor = executor else { + fatalError(" 请先 load ") + } + try inExecutor.predict(input: inTexture, dim: dim, completionHandle: { (result) in + let resultArr = self.fetchResult(paddleMobileRes: result) + completion(resultArr) + }, preProcessKernle: preprocessKernel, except: except) + } + + mutating func clear() { + executor?.clear() + program = nil + executor = nil + } + + func getTexture(image: CGImage, getTexture: @escaping (MTLTexture) -> Void) { + let texture = try? MetalHelper.shared.textureLoader.newTexture(cgImage: image, options: [:]) ?! " texture loader error" + MetalHelper.scaleTexture(queue: MetalHelper.shared.queue, input: texture!, size: (224, 224)) { (resTexture) in + getTexture(resTexture) + } + } + + func fetchResult(paddleMobileRes: ResultHolder) -> [Float32] { + return paddleMobileRes.resultArr + } + + // func predict() + +} diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/ViewController.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/ViewController.swift index 37151b3ba7819177ed99d5653dfb218752856d7a..9266f6fab88c897fe7a169f11ba2f6458af01b20 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/ViewController.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/ViewController.swift @@ -26,25 +26,21 @@ class ViewController: UIViewController { @IBOutlet weak var modelPickerView: UIPickerView! @IBOutlet weak var threadPickerView: UIPickerView! var selectImage: UIImage? - var program: Program? - var executor: Executor? var modelType: SupportModel = SupportModel.supportedModels()[0] var toPredictTexture: MTLTexture? - var modelHelper: Net { - return modelHelperMap[modelType] ?! " has no this type " + var net: Net { + get { + return modelHelperMap[modelType] ?! " has no this type " + } + set { + } } var threadNum = 1 @IBAction func loadAct(_ sender: Any) { - let inModelHelper = modelHelper - let queue = MetalHelper.shared.queue - let loader = Loader.init() + do { - let modelPath = inModelHelper.modelPath - let paraPath = inModelHelper.paramPath - - program = try loader.load(device: MetalHelper.shared.device, modelPath: modelPath, paraPath: paraPath) - executor = try Executor.init(inDevice: MetalHelper.shared.device, inQueue: queue, inProgram: program!) + try self.net.load() } catch let error { print(error) } @@ -58,9 +54,7 @@ class ViewController: UIViewController { } @IBAction func clearAct(_ sender: Any) { - executor?.clear() - program = nil - executor = nil + net.clear() } @IBAction func predictAct(_ sender: Any) { @@ -68,39 +62,54 @@ class ViewController: UIViewController { resultTextView.text = "请选择图片 ! " return } - - guard let inExecutor = executor else { - resultTextView.text = "请先 load ! " - return - } - do { - let max = 1 - var startDate = Date.init() - for i in 0.. { public let dim: [Int] public let resultArr: [P] - public var intermediateResults: [Variant]? + public var intermediateResults: [String : [Variant]]? public let elapsedTime: Double - public init(inDim: [Int], inResult: [P], inElapsedTime: Double, inIntermediateResults: [Variant]? = nil) { + public init(inDim: [Int], inResult: [P], inElapsedTime: Double, inIntermediateResults: [String : [Variant]]? = nil) { dim = inDim resultArr = inResult elapsedTime = inElapsedTime @@ -62,7 +62,7 @@ public class Executor { queue = inQueue for block in inProgram.programDesc.blocks { //block.ops.count - for i in 0..<(testTo + 1) { + for i in 0...shared.creat(device: inDevice, opDesc: op, scope: inProgram.scope) @@ -75,7 +75,7 @@ public class Executor { } } - public func predict(input: MTLTexture, expect: [Int], completionHandle: @escaping (ResultHolder

) -> Void, preProcessKernle: CusomKernel? = nil, except: Int = 0) throws { + public func predict(input: MTLTexture, dim: [Int], completionHandle: @escaping (ResultHolder

) -> Void, preProcessKernle: CusomKernel? = nil, except: Int = 0) throws { guard let buffer = queue.makeCommandBuffer() else { throw PaddleMobileError.predictError(message: "CommandBuffer is nil") } @@ -92,7 +92,7 @@ public class Executor { } let beforeDate = Date.init() - let inputTexture = InputTexture.init(inMTLTexture: resInput, inExpectDim: Dim.init(inDim: expect)) + let inputTexture = InputTexture.init(inMTLTexture: resInput, inExpectDim: Dim.init(inDim: dim)) program.scope.setInput(input: inputTexture) //(ops.count - except) for i in 0.. { } } - var outputTextures: [Variant]? + var outputTextures: [String : [Variant]]? if except > 0 { - outputTextures = ops[ops.count - except].inputs() + outputTextures = ops[ops.count - except].inputVariant() } buffer.addCompletedHandler { (commandbuffer) in @@ -130,13 +130,11 @@ public class Executor { } // return - self.ops[testTo].delogOutput() +// self.ops[testTo].delogOutput() // self.ops[91].delogOutput() // self.ops[92].delogOutput() // self.ops[93].delogOutput() - return; - let afterDate = Date.init() var resultHolder: ResultHolder

diff --git a/metal/paddle-mobile/paddle-mobile/Operators/Base/Operator.swift b/metal/paddle-mobile/paddle-mobile/Operators/Base/Operator.swift index 44f7bfd20ff9aa9e3c9dce1da3850acc4994cd46..424d55a7702cb2d8b04a62e2a93bb5ca11a1732e 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/Base/Operator.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/Base/Operator.swift @@ -25,7 +25,7 @@ protocol Runable { func run(device: MTLDevice, buffer: MTLCommandBuffer) throws func runImpl(device: MTLDevice,buffer: MTLCommandBuffer) throws func delogOutput() - func inputs() -> [Variant] + func inputVariant() -> [String : [Variant]] } extension Runable where Self: OperatorProtocol{ @@ -35,7 +35,10 @@ extension Runable where Self: OperatorProtocol{ } catch let error { throw error } -// print(type + ": " + para.outputDesc()) + } + + func inputVariant() -> [String : [Variant]] { + fatalError(" op \(type) need implement inputVariant") } func delogOutput() { @@ -98,6 +101,7 @@ class Operator : OperatorProtocol where let scope: Scope var kernel: KerType required init(device: MTLDevice, opDesc: OpDesc, inScope: Scope) throws { + print("create op: \(opDesc.type)") type = opDesc.type scope = inScope inputs = opDesc.inputs diff --git a/metal/paddle-mobile/paddle-mobile/Operators/BatchNormOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/BatchNormOp.swift index 1ed6fa7865e09437de047e01328f4f6747e6b1de..68441244a3915203a8909166d58aee172483364a 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/BatchNormOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/BatchNormOp.swift @@ -43,15 +43,11 @@ class BatchNormParam: OpParam { } class BatchNormOp: Operator, BatchNormParam

>, Runable, Creator, InferShaperable{ - - func inputs() -> [Variant] { - return [para.input, para.inputBias, para.inputMean, para.inputScale, para.inputVariance] - } - + typealias OpType = BatchNormOp

+ func inferShape() { para.output.dim = para.input.dim } - typealias OpType = BatchNormOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) diff --git a/metal/paddle-mobile/paddle-mobile/Operators/BoxcoderOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/BoxcoderOp.swift index 200b85b490edee58b1b290c1ce214bb9fc5aff45..eaa596e071b7628339be185a7e3599a370763041 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/BoxcoderOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/BoxcoderOp.swift @@ -1,104 +1,91 @@ - ///* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. - // - // Licensed under the Apache License, Version 2.0 (the "License"); - // you may not use this file except in compliance with the License. - // You may obtain a copy of the License at - // - // http://www.apache.org/licenses/LICENSE-2.0 - // - // Unless required by applicable law or agreed to in writing, software - // distributed under the License is distributed on an "AS IS" BASIS, - // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - // See the License for the specific language governing permissions and - // limitations under the License. */ +///* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. */ + +import Foundation + +class BoxcoderParam: OpParam { + typealias ParamPrecisionType = P + required init(opDesc: OpDesc, inScope: Scope) throws { + do { + priorBox = try BoxcoderParam.getFirstTensor(key: "PriorBox", map: opDesc.inputs, from: inScope) + priorBoxVar = try BoxcoderParam.getFirstTensor(key: "PriorBoxVar", map: opDesc.inputs, from: inScope) + targetBox = try BoxcoderParam.getFirstTensor(key: "TargetBox", map: opDesc.inputs, from: inScope) + output = try BoxcoderParam.getFirstTensor(key: "OutputBox", map: opDesc.outputs, from: inScope) + codeType = try BoxcoderParam.getAttr(key: "code_type", attrs: opDesc.attrs) + boxNormalized = try BoxcoderParam.getAttr(key: "box_normalized", attrs: opDesc.attrs) + } catch let error { + throw error + } + assert(priorBox.transpose == [0, 1, 2, 3]) + assert(priorBoxVar.transpose == [0, 1, 2, 3]) + assert(targetBox.transpose == [0, 1, 2, 3]) + assert(codeType == "decode_center_size") // encode_center_size is not implemented + assert((targetBox.tensorDim.cout() == 3) && (targetBox.tensorDim[0] == 1)) // N must be 1 (only handle batch size = 1) + } + let priorBox: Texture

+ let priorBoxVar: Texture

+ let targetBox: Texture

+ var output: Texture

+ let codeType: String + let boxNormalized: Bool +} + +class BoxcoderOp: Operator, BoxcoderParam

>, Runable, Creator, InferShaperable{ - import Foundation + typealias OpType = BoxcoderOp

+ + func inferShape() { + // para.output.dim = para.input.dim + } - class BoxcoderParam: OpParam { - typealias ParamPrecisionType = P - required init(opDesc: OpDesc, inScope: Scope) throws { - do { - priorBox = try BoxcoderParam.getFirstTensor(key: "PriorBox", map: opDesc.inputs, from: inScope) - priorBoxVar = try BoxcoderParam.getFirstTensor(key: "PriorBoxVar", map: opDesc.inputs, from: inScope) - targetBox = try BoxcoderParam.getFirstTensor(key: "TargetBox", map: opDesc.inputs, from: inScope) - output = try BoxcoderParam.getFirstTensor(key: "OutputBox", map: opDesc.outputs, from: inScope) - codeType = try BoxcoderParam.getAttr(key: "code_type", attrs: opDesc.attrs) - boxNormalized = try BoxcoderParam.getAttr(key: "box_normalized", attrs: opDesc.attrs) - } catch let error { - throw error - } - assert(priorBox.transpose == [0, 1, 2, 3]) - assert(priorBoxVar.transpose == [0, 1, 2, 3]) - assert(targetBox.transpose == [0, 1, 2, 3]) - assert(codeType == "decode_center_size") // encode_center_size is not implemented - assert((targetBox.tensorDim.cout() == 3) && (targetBox.tensorDim[0] == 1)) // N must be 1 (only handle batch size = 1) + func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { + do { + try kernel.compute(commandBuffer: buffer, param: para) + } catch let error { + throw error } - let priorBox: Texture

- let priorBoxVar: Texture

- let targetBox: Texture

- var output: Texture

- let codeType: String - let boxNormalized: Bool } - class BoxcoderOp: Operator, BoxcoderParam

>, Runable, Creator, InferShaperable{ + func delogOutput() { - func inputs() -> [Variant] { - return [para.priorBox, para.priorBoxVar, para.targetBox] - } + print(" \(type) output: ") + let priorBoxOriginDim = para.priorBox.originDim + let priorBoxArray = para.priorBox.metalTexture.realNHWC(dim: (n: priorBoxOriginDim[0], h: priorBoxOriginDim[1], w: priorBoxOriginDim[2], c: priorBoxOriginDim[3])) + print(" prior box ") + print(priorBoxArray.strideArray()) - func inferShape() { - // para.output.dim = para.input.dim - } + let priorBoxVarOriginDim = para.priorBoxVar.originDim + let priorBoxVarArray = para.priorBoxVar.metalTexture.realNHWC(dim: (n: priorBoxVarOriginDim[0], h: priorBoxVarOriginDim[1], w: priorBoxVarOriginDim[2], c: priorBoxVarOriginDim[3])) + print(" prior box var ") + print(priorBoxVarArray.strideArray()) - typealias OpType = BoxcoderOp

- func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } - } + let targetBoxOriginDim = para.targetBox.originDim + let targetBoxArray = para.targetBox.metalTexture.realNHWC(dim: (n: targetBoxOriginDim[0], h: targetBoxOriginDim[1], w: targetBoxOriginDim[2], c: targetBoxOriginDim[3])) + print(" target box ") + print(targetBoxArray.strideArray()) - func delogOutput() { -// let outputArray = para.output.metalTexture.floatArray { (o: Float32) -> Float32 in -// return o -// } - - let priorBoxOriginDim = para.priorBox.originDim - let priorBoxArray = para.priorBox.metalTexture.realNHWC(dim: (n: priorBoxOriginDim[0], h: priorBoxOriginDim[1], w: priorBoxOriginDim[2], c: priorBoxOriginDim[3])) - print(" prior box ") - print(priorBoxArray.strideArray()) - - - let priorBoxVarOriginDim = para.priorBoxVar.originDim - let priorBoxVarArray = para.priorBoxVar.metalTexture.realNHWC(dim: (n: priorBoxVarOriginDim[0], h: priorBoxVarOriginDim[1], w: priorBoxVarOriginDim[2], c: priorBoxVarOriginDim[3])) - print(" prior box var ") - print(priorBoxVarArray.strideArray()) - - let targetBoxOriginDim = para.targetBox.originDim - let targetBoxArray = para.targetBox.metalTexture.realNHWC(dim: (n: targetBoxOriginDim[0], h: targetBoxOriginDim[1], w: targetBoxOriginDim[2], c: targetBoxOriginDim[3])) - print(" target box ") - print(targetBoxArray.strideArray()) - - - let originDim = para.output.originDim - - let outputArray = para.output.metalTexture.realNHWC(dim: (n: originDim[0], h: originDim[1], w: originDim[2], c: originDim[3])) - print(outputArray.strideArray()) - - -// print(outputArray.strideArray()) - //box_coder_0.tmp_0 -// writeToLibrary(fileName: "boxcoder_output", array: outputArray) -// print(para.output.metalTexture) -// print(" write done ") - } + let originDim = para.output.originDim + + let outputArray = para.output.metalTexture.realNHWC(dim: (n: originDim[0], h: originDim[1], w: originDim[2], c: originDim[3])) + print(outputArray.strideArray()) } - - - - - +} + + + + + + diff --git a/metal/paddle-mobile/paddle-mobile/Operators/ConcatOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/ConcatOp.swift index 986ffbb725dd26e5f458d27a89b45d902f93dae5..ba9c6de773c4e86f2a2bf68fea7bfa1ec5dc5c4e 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/ConcatOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/ConcatOp.swift @@ -40,16 +40,13 @@ class ConcatParam: OpParam { class ConcatOp: Operator, ConcatParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return para.input - } - + typealias OpType = ConcatOp

+ func inferShape() { // let dim = para.input.reduce([0, 0]) {[$0[0] + $1.dim[0], $1.dim[1]]} // para.output.dim = Dim.init(inDim: dim) } - typealias OpType = ConcatOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) @@ -59,34 +56,10 @@ class ConcatOp: Operator, ConcatParam

>, Run } func delogOutput() { - - - + print(" \(type) output: ") let originDim = para.output.originDim let outputArray = para.output.metalTexture.realNHWC(dim: (n: originDim[0], h: originDim[1], w: originDim[2], c: originDim[3])) print(outputArray.strideArray()) - - -// let outputArray = para.output.metalTexture.floatArray { (o: Float32) -> Float32 in -// return o -// } -// -//// print(outputArray.strideArray()) -// -// writeToLibrary(fileName: "concat_out", array: outputArray) -// -// let device: MTLDevice = MTLCreateSystemDefaultDevice()! - -// let tensorArray: [P] = device.texture2tensor(texture: para.output.metalTexture, dim: [1917, 4]) - -// print(tensorArray.strideArray()) - -// print(para.output.metalTexture) - -// writeToLibrary(fileName: "concat_out", array: outputArray) -// print(" write done ") - -// print(outputArray.strideArray()) } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/ConvAddBatchNormReluOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/ConvAddBatchNormReluOp.swift index f037cc69287022a9be39fc0416daed0001dda86a..a5b1312e7cfc4982b06e0ee7912bba158c0e4d54 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/ConvAddBatchNormReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/ConvAddBatchNormReluOp.swift @@ -61,10 +61,6 @@ class ConvAddBatchNormReluParam: OpParam { class ConvAddBatchNormReluOp: Operator, ConvAddBatchNormReluParam

>, Runable, Creator, InferShaperable, Fusion{ - func inputs() -> [Variant] { - return [para.variance, para.bias, para.mean, para.scale, para.y, para.filter, para.input] - } - typealias OpType = ConvAddBatchNormReluOp

func inferShape() { @@ -115,7 +111,8 @@ class ConvAddBatchNormReluOp: Operator: OpParam { } class ConvAddOp: Operator, ConvAddParam

>, Runable, Creator, InferShaperable, Fusion{ - - func delogOutput() { - print(para.output.metalTexture.toTensor(dim: (n: para.output.tensorDim[0], c: para.output.tensorDim[1], h: para.output.tensorDim[2], w: para.output.tensorDim[3])).strideArray()) + typealias OpType = ConvAddOp

-// print(" conv add: ") - - -// print(para.input.metalTexture) - -// print(" filter array: ") -// let filterArray: [P] = para.filter.buffer.array() -// print(filterArray) - -// let input = para.input.metalTexture.floatArray { (p: P) -> P in -// return p -// } -// print(input) - -// let output = para.output.metalTexture.floatArray { (p: P) -> P in -// return p -// } -// print(para.output.metalTexture) -// print(output) - } + static func fusionNode() -> Node { @@ -80,16 +59,10 @@ class ConvAddOp: Operator, ConvAddParam

>, return [:] } - func inputs() -> [Variant] { - return [para.input, para.y, para.filter] - } - - static func fusionType() -> String { return gConvAddType } - typealias OpType = ConvAddOp

func inferShape() { @@ -122,4 +95,7 @@ class ConvAddOp: Operator, ConvAddParam

>, } } + func delogOutput() { + print(para.output.metalTexture.toTensor(dim: (n: para.output.tensorDim[0], c: para.output.tensorDim[1], h: para.output.tensorDim[2], w: para.output.tensorDim[3])).strideArray()) + } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/ConvBNReluOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/ConvBNReluOp.swift index f81048832340b080f6a147e064338f8f8ad5500d..3c521a2210614550577369c603dbbdc5e2cb6692 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/ConvBNReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/ConvBNReluOp.swift @@ -109,74 +109,8 @@ class ConvBNReluOp: Operator, ConvBNReluPa } func delogOutput() { - - // let _: P? = para.input.metalTexture.logDesc(header: "conv add batchnorm relu input: ", stridable: false) - // para.filter.logDataPointer(header: "filter data pointer: ") - // print("filter: \(para.filter)") - - // print("biase: \(para.y)") - // print("padding: \(para.paddings)") - // print("stride: \(para.stride)") - - // let _: P? = para.y.buffer?.logDesc(header: " biase: ", stridable: false) - // let _: P? = para.newBiase?.logDesc(header: "new biase: ", stridable: false) - // let _: P? = para.newScale?.logDesc(header: "new scale: ", stridable: false) - - - -// print("input: ") -// print(para.input.metalTexture) -// -// let input = para.input.metalTexture.floatArray { (p: P) -> P in -// return p -// } -// for i in 0...size) { -// print("index: \(i) \(newScale![i]) ") -// } -// -// print("new biase: ") -// for i in 0..<(para.newBiase!.length / MemoryLayout

.size) { -// print("index: \(i) \(newBiase![i]) ") -// } - -// print(para.output.metalTexture) -// -// -// -// let output = para.output.metalTexture.floatArray { (p: P) -> P in -// return p -// } -// print(output) -// - -// -// writeToLibrary(fileName: "batch_norm_34.tmp_2", array: output) -// print(" write done") -// - - - print(para.output.metalTexture.toTensor(dim: (n: para.output.tensorDim[0], c: para.output.tensorDim[1], h: para.output.tensorDim[2], w: para.output.tensorDim[3])).strideArray()) - - // let _: P? = para.output.metalTexture.logDesc(header: "conv add batchnorm relu output: ", stridable: true) + print(" \(type) output: ") + print(para.output.metalTexture.toTensor(dim: (n: para.output.originDim[0], c: para.output.originDim[1], h: para.output.originDim[2], w: para.output.originDim[3])).strideArray()) } + } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/ConvOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/ConvOp.swift index 8a76a39284bba84cd87b7df12f4516efc778fdc7..98f4a077671bbc3161f147bf73c9691dd1f86536 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/ConvOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/ConvOp.swift @@ -41,19 +41,8 @@ class ConvParam: OpParam { } class ConvOp: Operator, ConvParam

>, Runable, Creator, InferShaperable { - - func inputs() -> [Variant] { - return [para.input, para.filter] - } - - required init(device: MTLDevice, opDesc: OpDesc, inScope: Scope) throws { - do { - try super.init(device: device, opDesc: opDesc, inScope: inScope) - } catch let error { - throw error - } - - } + typealias OpType = ConvOp

+ func inferShape() { let inDims = para.input.dim let filterDim = para.filter.dim @@ -76,7 +65,6 @@ class ConvOp: Operator, ConvParam

>, Runable, para.output.dim = Dim.init(inDim: outDim) } - typealias OpType = ConvOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) @@ -87,7 +75,7 @@ class ConvOp: Operator, ConvParam

>, Runable, func delogOutput() { print("conv output : ") - print(para.output.metalTexture) + print(para.output.metalTexture.toTensor(dim: (n: para.output.originDim[0], c: para.output.originDim[1], h: para.output.originDim[2], w: para.output.originDim[3])).strideArray()) // let _: Float16? = para.output.metalTexture.logDesc() } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/ConvTransposeOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/ConvTransposeOp.swift index 206828e3a0a631061d60ac480dcf870f32f9737f..cf67ef7ccf085996c49095ba0b3d41c50ff7fbe4 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/ConvTransposeOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/ConvTransposeOp.swift @@ -28,15 +28,12 @@ class ConvTransposeParam: ConvParam

{ class ConvTransposeOp: Operator, ConvTransposeParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return [para.input, para.filter] - } + typealias OpType = ConvTransposeOp

func inferShape() { // para.output.dim = para.input.dim } - typealias OpType = ConvTransposeOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) @@ -44,6 +41,7 @@ class ConvTransposeOp: Operator, ConvTr throw error } } + func delogOutput() { print("conv transpose delog") let _: P? = para.input.metalTexture.logDesc(header: "conv transpose input: ", stridable: true) diff --git a/metal/paddle-mobile/paddle-mobile/Operators/DepthwiseConvOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/DepthwiseConvOp.swift index b6f1e116b1f848857a1b04d038e34af416d98dd5..639c22ce12c7a110cf58f3f9e7b9ee458d393260 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/DepthwiseConvOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/DepthwiseConvOp.swift @@ -15,11 +15,9 @@ import Foundation class DepthConvOp: Operator, ConvParam

>, Runable, Creator, InferShaperable { - - func inputs() -> [Variant] { - return [para.input, para.filter] - } - + + typealias OpType = DepthConvOp

+ required init(device: MTLDevice, opDesc: OpDesc, inScope: Scope) throws { do { try super.init(device: device, opDesc: opDesc, inScope: inScope) @@ -50,8 +48,6 @@ class DepthConvOp: Operator, ConvParam

>, Runa para.output.dim = Dim.init(inDim: outDim) } - typealias OpType = DepthConvOp

- func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) @@ -61,8 +57,7 @@ class DepthConvOp: Operator, ConvParam

>, Runa } func delogOutput() { - print("conv output : ") - print(para.output.metalTexture) - // let _: Float16? = para.output.metalTexture.logDesc() + print(" \(type) output: ") + print(para.output.metalTexture.toTensor(dim: (n: para.output.originDim[0], c: para.output.originDim[1], h: para.output.originDim[2], w: para.output.originDim[3])).strideArray()) } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/DwConvBNReluOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/DwConvBNReluOp.swift index 15d2b262f332fc9fb7af6da611c05ff9ac4b0249..16a42d5c7b24e7b3a26cab35f68decd226076876 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/DwConvBNReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/DwConvBNReluOp.swift @@ -17,10 +17,6 @@ import Foundation class DwConvBNReluOp: Operator, ConvBNReluParam

>, Runable, Creator, InferShaperable, Fusion{ typealias OpType = ConvBNReluOp

- func inputs() -> [Variant] { - return [para.input, para.bias, para.mean, para.filter, para.variance, para.scale] - } - func inferShape() { let inDims = para.input.dim let filterDim = para.filter.dim @@ -68,26 +64,7 @@ class DwConvBNReluOp: Operator, ConvBNRelu } func delogOutput() { - - // let _: P? = para.input.metalTexture.logDesc(header: "conv add batchnorm relu input: ", stridable: false) - // para.filter.logDataPointer(header: "filter data pointer: ") - // print("filter: \(para.filter)") - - // print("biase: \(para.y)") - // print("padding: \(para.paddings)") - // print("stride: \(para.stride)") - - // let _: P? = para.y.buffer?.logDesc(header: " biase: ", stridable: false) - // let _: P? = para.newBiase?.logDesc(header: "new biase: ", stridable: false) - // let _: P? = para.newScale?.logDesc(header: "new scale: ", stridable: false) - -// let output = para.output.metalTexture.floatArray { (p: P) -> P in -// return p -// } -// -// writeToLibrary(fileName: "batch_norm_19.tmp_2", array: output) -// print(" write done") - - // let _: P? = para.output.metalTexture.logDesc(header: "conv add batchnorm relu output: ", stridable: false) + print(" \(type) output: ") + print(para.output.metalTexture.toTensor(dim: (n: para.output.originDim[0], c: para.output.originDim[1], h: para.output.originDim[2], w: para.output.originDim[3])).strideArray()) } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/ElementwiseAddOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/ElementwiseAddOp.swift index b4760f1afe489ec13238aeb6d50ac1e416d88478..aeb1bea230a25623fce7c73f5025e166f501a7c6 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/ElementwiseAddOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/ElementwiseAddOp.swift @@ -34,16 +34,12 @@ class ElementwiseAddParam: OpParam { } class ElementwiseAddOp: Operator, ElementwiseAddParam

>, Runable, Creator, InferShaperable{ - - func inputs() -> [Variant] { - return [para.input, para.inputY] - } + typealias OpType = ElementwiseAddOp

func inferShape() { para.output.dim = para.input.dim } - typealias OpType = ElementwiseAddOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/FeedOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/FeedOp.swift index 43554a84d6fc1a0d946c6c8da9a5bb10cf2e52e7..59e5443a0f8c372dc366e2e1c65422dffbf42252 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/FeedOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/FeedOp.swift @@ -35,11 +35,7 @@ class FeedParam: OpParam{ class FeedOp: Operator, FeedParam

>, Runable, Creator, InferShaperable { typealias OpType = FeedOp

- - func inputs() -> [Variant] { - return [para.input] - } - + func inferShape() { // print("feed input: \(para.input.expectDim)") print("feed output: \(para.output.dim)") diff --git a/metal/paddle-mobile/paddle-mobile/Operators/FetchOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/FetchOp.swift index 1bedd030b1232d4086a5d67455a57c940ed0e1a1..f38386db1e1f1db292f2421bb8105099c3a5bd92 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/FetchOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/FetchOp.swift @@ -37,20 +37,18 @@ class FetchKernel: Kernel, Computable { } required init(device: MTLDevice, param: FetchParam

) { - super.init(device: device, inFunctionName: "texture2d_to_2d_array") + super.init(device: device, inFunctionName: "place_holder") } } class FetchOp: Operator< FetchKernel

, FetchParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return [para.input] - } + typealias OpType = FetchOp

+ func inferShape() { print(para.input.dim) } - typealias OpType = FetchOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { scope.setOutput(output: para.output) } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/ConvTransposeKernel.swift b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/ConvTransposeKernel.swift index 0b11e717693a5c51a58b2c16ebd1ccf4ee135ec9..6725cd109410a088945da71b34f6d09080e7052e 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/ConvTransposeKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/ConvTransposeKernel.swift @@ -43,7 +43,6 @@ class ConvTransposeKernel: Kernel, Computable{ let dilationY = UInt16(param.dilations[1]) metalParam = MetalConvTransposeParam.init(kernelW: kernelWidth, kernelH: kernelHeight, strideX: strideX, strideY: strideY, paddingX: paddingX, paddingY: paddingY, dilationX: dilationX, dilationY: dilationY) - } func compute(commandBuffer: MTLCommandBuffer, param: ConvTransposeParam

) throws { diff --git a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/MulticlassNMSKernel.swift b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/MulticlassNMSKernel.swift index 91517143819eff9d3564f3315fbf08310d03b081..5ee4a5b31c5ee22cf28bf54fd8f7df13d14f9610 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/MulticlassNMSKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/MulticlassNMSKernel.swift @@ -15,17 +15,11 @@ import Foundation class MulticlassNMSKernel: Kernel, Computable{ - func compute(commandBuffer: MTLCommandBuffer, param: MulticlassNMSParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") - } -// encoder.setTexture(param.input.metalTexture, index: 0) -// encoder.setTexture(param.output.metalTexture, index: 1) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() - } - - required init(device: MTLDevice, param: MulticlassNMSParam

) { - super.init(device: device, inFunctionName: "prior_box") - } + + required init(device: MTLDevice, param: MulticlassNMSParam

) { + super.init(device: device, inFunctionName: "place_holder") + } + + func compute(commandBuffer: MTLCommandBuffer, param: MulticlassNMSParam

) throws { + } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/PoolKernel.swift b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/PoolKernel.swift index 983a3acb9943f2e549b07d095c7dd4a23c1e96d9..a6487d8f1569373433e6076c49151992bdf7d965 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/PoolKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/PoolKernel.swift @@ -15,46 +15,48 @@ import Foundation struct PoolMetalParam { - let ksizeX: Int32 - let ksizeY: Int32 - let strideX: Int32 - let strideY: Int32 - let paddingX: Int32 - let paddingY: Int32 - let poolType: Int32 + let ksizeX: Int32 + let ksizeY: Int32 + let strideX: Int32 + let strideY: Int32 + let paddingX: Int32 + let paddingY: Int32 + let poolType: Int32 } class PoolKernel: Kernel, Computable{ - func compute(commandBuffer: MTLCommandBuffer, param: PoolParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") - } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - var poolType: Int32 - switch param.poolType { - case "max": - poolType = 0 - case "avg": - poolType = 1 - default: - throw PaddleMobileError.predictError(message: " unknown pooltype " + param.poolType) - } - var pmp = PoolMetalParam.init( - ksizeX: param.ksize[0], - ksizeY: param.ksize[1], - strideX: param.stride[0], - strideY: param.stride[1], - paddingX: param.padding[0], - paddingY: param.padding[1], - poolType: poolType - ) - encoder.setBytes(&pmp, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() + + required init(device: MTLDevice, param: PoolParam

) { + super.init(device: device, inFunctionName: "pool") + param.output.initTexture(device: device) + } + + func compute(commandBuffer: MTLCommandBuffer, param: PoolParam

) throws { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.predictError(message: " encoder is nil") } - - required init(device: MTLDevice, param: PoolParam

) { - super.init(device: device, inFunctionName: "pool") + encoder.setTexture(param.input.metalTexture, index: 0) + encoder.setTexture(param.output.metalTexture, index: 1) + var poolType: Int32 + switch param.poolType { + case "max": + poolType = 0 + case "avg": + poolType = 1 + default: + throw PaddleMobileError.predictError(message: " unknown pooltype " + param.poolType) } + var pmp = PoolMetalParam.init( + ksizeX: param.ksize[0], + ksizeY: param.ksize[1], + strideX: param.stride[0], + strideY: param.stride[1], + paddingX: param.padding[0], + paddingY: param.padding[1], + poolType: poolType + ) + encoder.setBytes(&pmp, length: MemoryLayout.size, index: 0) + encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) + encoder.endEncoding() + } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/metal/Common.metal b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/metal/Common.metal index 50ad15597b974f75b67bc81a2b49cae4b665bc1f..c5c4ffc5c995500503411148db31b2acfa3459b6 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/metal/Common.metal +++ b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/metal/Common.metal @@ -1,10 +1,16 @@ -// -// common.metal -// paddle-mobile -// -// Created by liuRuiLong on 2018/8/26. -// Copyright © 2018年 orange. All rights reserved. -// +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. */ #include using namespace metal; diff --git a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/metal/Kernels.metal b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/metal/Kernels.metal index fd618e15342bbffb6ff7358e42965e734c42ddda..1e135e609b7000db72768491641cbf178bed074b 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/Kernels/metal/Kernels.metal +++ b/metal/paddle-mobile/paddle-mobile/Operators/Kernels/metal/Kernels.metal @@ -16,6 +16,12 @@ #include "Common.metal" using namespace metal; +// 占位函数, 啥也没干 +kernel void place_holder(texture2d inTexture [[texture(0)]], + texture2d_array outTexture [[texture(1)]], + uint3 gid [[thread_position_in_grid]]) { +} + struct OutputDim { ushort width; ushort height; @@ -161,9 +167,6 @@ kernel void pool_half(texture2d_array inTexture [[texture(0) outTexture.write(r, gid.xy, gid.z); } - - - struct TransposeParam { int iC; int oC; diff --git a/metal/paddle-mobile/paddle-mobile/Operators/MulticlassNMSOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/MulticlassNMSOp.swift index 590427d9eff883a069f8a96509db50b01f4272e9..6220a584e725042f454b02777a79caeaae2a52e1 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/MulticlassNMSOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/MulticlassNMSOp.swift @@ -15,39 +15,39 @@ import Foundation class MulticlassNMSParam: OpParam { - typealias ParamPrecisionType = P - required init(opDesc: OpDesc, inScope: Scope) throws { - do { - scores = try MulticlassNMSParam.getFirstTensor(key: "Scores", map: opDesc.inputs, from: inScope) - bboxes = try MulticlassNMSParam.getFirstTensor(key: "BBoxes", map: opDesc.inputs, from: inScope) - output = try MulticlassNMSParam.outputOut(outputs: opDesc.outputs, from: inScope) - } catch let error { - throw error - } + typealias ParamPrecisionType = P + required init(opDesc: OpDesc, inScope: Scope) throws { + do { + scores = try MulticlassNMSParam.getFirstTensor(key: "Scores", map: opDesc.inputs, from: inScope) + bboxes = try MulticlassNMSParam.getFirstTensor(key: "BBoxes", map: opDesc.inputs, from: inScope) + output = try MulticlassNMSParam.outputOut(outputs: opDesc.outputs, from: inScope) + } catch let error { + throw error } - let scores: Texture

- let bboxes: Texture

- var output: Texture

+ } + let scores: Texture

+ let bboxes: Texture

+ var output: Texture

} class MulticlassNMSOp: Operator, MulticlassNMSParam

>, Runable, Creator, InferShaperable{ + + func inputVariant() -> [String : [Variant]] { + return ["Scores" : [para.scores], "BBoxes" : [para.bboxes]] + } - func inputs() -> [Variant] { - return [para.scores,para.bboxes] + func inferShape() { + // para.output.dim = para.input.dim } - func inferShape() { -// para.output.dim = para.input.dim - } - - typealias OpType = MulticlassNMSOp

- func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + typealias OpType = MulticlassNMSOp

+ func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { + do { + try kernel.compute(commandBuffer: buffer, param: para) + } catch let error { + throw error } + } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/PoolOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/PoolOp.swift index 0c2ae767f80a96ca0ea7d03014050d23a1987cb6..54fd7ce8e28ca68e0799cd0865564e9d16b648bc 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/PoolOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/PoolOp.swift @@ -43,15 +43,12 @@ class PoolParam: OpParam { class PoolOp: Operator, PoolParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return [para.input] - } - + typealias OpType = PoolOp

+ func inferShape() { // para.output.dim = para.input.dim } - typealias OpType = PoolOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) diff --git a/metal/paddle-mobile/paddle-mobile/Operators/PreluOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/PreluOp.swift index 1b55c1f3cbbb417ebd36d914b563ae3c491f3565..dff120226b6d65ceae32120b1149f21fd45456f2 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/PreluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/PreluOp.swift @@ -35,15 +35,12 @@ class PreluParam: OpParam { class PreluOp: Operator, PreluParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return [para.alpha, para.input] - } - + typealias OpType = PreluOp

+ func inferShape() { // para.output.dim = para.input.dim } - typealias OpType = PreluOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) @@ -51,6 +48,7 @@ class PreluOp: Operator, PreluParam

>, Runabl throw error } } + func delogOutput() { print("softmax delog") let _: P? = para.input.metalTexture.logDesc(header: "softmax input: ", stridable: false) diff --git a/metal/paddle-mobile/paddle-mobile/Operators/PriorBoxOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/PriorBoxOp.swift index 8610ab7a90bd444f9c79c1c16c53dad25d9efb00..7e82fdec37fb7bd66181fde3af01aedbaf87a023 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/PriorBoxOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/PriorBoxOp.swift @@ -55,15 +55,11 @@ class PriorBoxParam: OpParam { class PriorBoxOp: Operator, PriorBoxParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return [para.input, para.inputImage] - } - - + typealias OpType = PriorBoxOp

+ func inferShape() { } - typealias OpType = PriorBoxOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) @@ -73,8 +69,8 @@ class PriorBoxOp: Operator, PriorBoxParam

} func delogOutput() { - print("pribox: ") - print("output: ") + print(" \(type) output: ") + // output let outputArray = para.output.metalTexture.floatArray { (o: Float32) -> Float32 in return o @@ -93,9 +89,6 @@ class PriorBoxOp: Operator, PriorBoxParam

// writeToLibrary(fileName: "variance_out", array: outputVarianceArray) - print("pribox write done ") - - } } diff --git a/metal/paddle-mobile/paddle-mobile/Operators/ReluOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/ReluOp.swift index 5d75f8ae816a9af6da1f5e2b480667b30116aa06..5918d7088539345f99ece23a03cc427cfa62771f 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/ReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/ReluOp.swift @@ -30,15 +30,12 @@ class ReluParam: OpParam { class ReluOp: Operator, ReluParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return [para.input] - } + typealias OpType = ReluOp

func inferShape() { para.output.dim = para.input.dim } - typealias OpType = ReluOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) diff --git a/metal/paddle-mobile/paddle-mobile/Operators/ReshapeOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/ReshapeOp.swift index 9bbe07422df07d255a19c86147b4ae9165643e64..373c448b16d3a597f28884ee2e70b29c152f5526 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/ReshapeOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/ReshapeOp.swift @@ -57,15 +57,12 @@ class ReshapeParam: OpParam { class ReshapeOp: Operator, ReshapeParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return [para.input] - } - + typealias OpType = ReshapeOp

+ func inferShape() { // para.output.dim = para.input.dim } - typealias OpType = ReshapeOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) diff --git a/metal/paddle-mobile/paddle-mobile/Operators/SoftmaxOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/SoftmaxOp.swift index 22637b09ce3844ff4bf72c685acbfe1141c75765..0eddca3eb9ce21982954c28e5484f94eb5cacbe1 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/SoftmaxOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/SoftmaxOp.swift @@ -36,16 +36,12 @@ class SoftmaxParam: OpParam { } class SoftmaxOp: Operator, SoftmaxParam

>, Runable, Creator, InferShaperable{ - - func inputs() -> [Variant] { - return [para.input] - } - + typealias OpType = SoftmaxOp

+ func inferShape() { // para.output.dim = para.input.dim } - typealias OpType = SoftmaxOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) @@ -53,6 +49,7 @@ class SoftmaxOp: Operator, SoftmaxParam

>, throw error } } + func delogOutput() { print("softmax delog") diff --git a/metal/paddle-mobile/paddle-mobile/Operators/TransposeOp.swift b/metal/paddle-mobile/paddle-mobile/Operators/TransposeOp.swift index 1e3390c7e813389c4c13aab91ba146fbaea8a224..3f05a3db3e0de7abaa208ba8b0700688fe349d4e 100644 --- a/metal/paddle-mobile/paddle-mobile/Operators/TransposeOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Operators/TransposeOp.swift @@ -32,15 +32,12 @@ class TransposeParam: OpParam { class TransposeOp: Operator, TransposeParam

>, Runable, Creator, InferShaperable{ - func inputs() -> [Variant] { - return [para.input] - } - + typealias OpType = TransposeOp

+ func inferShape() { //para.output.dim = para.input.dim } - typealias OpType = TransposeOp

func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { do { try kernel.compute(commandBuffer: buffer, param: para) @@ -48,32 +45,13 @@ class TransposeOp: Operator, TransposeParam throw error } } + func delogOutput() { - print(para.output.metalTexture.realNHWC(dim: (n: para.output.originDim[0], h: para.output.originDim[1], w: para.output.originDim[2], c: para.output.originDim[3])).strideArray()) - -// print(para.input.metalTexture.toTensor(dim: (n: para.input.originDim[0], c: para.input.originDim[1], h: para.input.originDim[2], w: para.input.originDim[3])).strideArray()) -// -// -// let originDim = para.output.tensorDim -// let outputArray = para.output.metalTexture.realNHWC(dim: (n: originDim[0], h: originDim[1], w: originDim[2], c: originDim[3])) -// print(outputArray.strideArray()) - - -// let inputArray: [Float32] = para.input.metalTexture.floatArray { (ele: Float32) -> Float32 in -// return ele -// } -// -// print(inputArray.strideArray()) -// -// let outputArray: [Float32] = para.output.metalTexture.floatArray { (ele: Float32) -> Float32 in -// return ele -// } -// -// print(outputArray.strideArray()) - -// writeToLibrary(fileName: "transpose_ouput", array: outputArray) + print(" \(type) output: ") + let originDim = para.output.tensorDim + let outputArray = para.output.metalTexture.realNHWC(dim: (n: originDim[0], h: originDim[1], w: originDim[2], c: originDim[3])) + print(outputArray.strideArray()) } - }