From 68a0bada3c2c9930e3a7f81c6458a5d5f4fdfa15 Mon Sep 17 00:00:00 2001 From: NazgulLee Date: Thu, 25 Jul 2019 10:31:53 +0800 Subject: [PATCH] 1.merge workshop; 2.remove scale op mps implementation (#1765) --- .../MobileNetDemo/MobileNet.swift | 25 +- .../MobileNetDemo/ViewController.swift | 5 +- .../project.pbxproj | 457 +++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/PaddleMobileTest.xcscheme | 91 ++++ .../PaddleMobileTest/AppDelegate.swift | 46 ++ .../AppIcon.appiconset/Contents.json | 98 ++++ .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../Base.lproj/Main.storyboard | 45 ++ .../PaddleMobileTest/Info.plist | 52 ++ .../PaddleMobileTest/TestViewController.swift | 466 ++++++++++++++++++ .../PaddleMobileTest/ViewController.swift | 122 +++++ metal/Podfile | 6 + .../MultiPredictViewController.swift | 8 +- .../paddle-mobile-demo/Net/Genet.swift | 31 +- .../paddle-mobile-demo/Net/MobileNet.swift | 33 +- .../Net/MobileNetCombined.swift | 26 +- .../paddle-mobile-demo/Net/MobileNetSSD.swift | 77 +-- .../Net/MobilenetSSD_AR.swift | 132 +---- .../paddle-mobile-demo/Net/YoloNet.swift | 21 +- .../OCInterface/PaddleMobileGPU.m | 9 +- .../OCInterface/SuperResolutionNet.swift | 35 +- .../paddle-mobile-demo/ViewController.swift | 51 +- .../BufferToTexture.metal | 31 ++ .../paddle-mobile.xcodeproj/project.pbxproj | 8 + .../paddle-mobile/paddle-mobile/API/Net.swift | 11 +- .../paddle-mobile/API/Runner.swift | 260 ++++++++-- .../paddle-mobile/Src/Common/Errors.swift | 32 ++ .../paddle-mobile/Src/Common/Extensions.swift | 29 +- .../Src/Common/MetalExtension.swift | 227 +++++---- .../Src/Common/PaddleMobileUnitTest.swift | 35 +- .../paddle-mobile/Src/Common/Tools.swift | 26 +- .../paddle-mobile/Src/Common/Types.swift | 66 +-- .../paddle-mobile/Src/Framework/Dim.swift | 5 +- .../Src/Framework/Executor.swift | 34 +- .../paddle-mobile/Src/Framework/Loader.swift | 117 ++--- .../paddle-mobile/Src/Framework/Tensor.swift | 117 +++-- .../paddle-mobile/Src/Framework/Texture.swift | 81 ++- .../paddle-mobile/Src/Framework/Utils.swift | 29 ++ .../Src/Operators/Base/OpCreator.swift | 8 +- .../Src/Operators/Base/OpParam.swift | 133 ++--- .../Src/Operators/Base/Operator.swift | 41 +- .../Src/Operators/BatchNormOp.swift | 34 +- .../Src/Operators/BilinearInterpOp.swift | 25 +- .../Src/Operators/BoxcoderOp.swift | 56 +-- .../Src/Operators/ConcatOp.swift | 59 +-- .../Src/Operators/ConvAddAddPreluOp.swift | 36 +- .../Operators/ConvAddBatchNormReluOp.swift | 47 +- .../Src/Operators/ConvAddOp.swift | 14 +- .../Src/Operators/ConvAddPreluOp.swift | 36 +- .../Src/Operators/ConvAddReluOp.swift | 18 +- .../Src/Operators/ConvBNReluOp.swift | 42 +- .../paddle-mobile/Src/Operators/ConvOp.swift | 31 +- .../Src/Operators/ConvReluOp.swift | 7 +- .../Src/Operators/ConvTransposeOp.swift | 31 +- .../Src/Operators/DepthwiseConvOp.swift | 12 +- .../Src/Operators/DwConvBNReluOp.swift | 12 +- .../Src/Operators/ElementwiseAddOp.swift | 57 +-- .../Src/Operators/ElementwiseAddPreluOp.swift | 60 +-- .../paddle-mobile/Src/Operators/ExpOp.swift | 22 +- .../paddle-mobile/Src/Operators/FeedOp.swift | 23 +- .../paddle-mobile/Src/Operators/FetchOp.swift | 22 +- .../Src/Operators/FlattenOp.swift | 49 +- .../Src/Operators/Kernels/Base/Kernel.swift | 121 +++-- .../Operators/Kernels/BatchNormKernel.swift | 47 +- .../Kernels/BilinearInterpKernel.swift | 40 +- .../Operators/Kernels/BoxcoderKernel.swift | 51 +- .../Src/Operators/Kernels/ConcatKernel.swift | 56 ++- .../Kernels/ConvAddAddPreluKernel.swift | 158 +++--- .../Kernels/ConvAddBatchNormReluKernel.swift | 166 ++++--- .../Src/Operators/Kernels/ConvAddKernel.swift | 2 +- .../Kernels/ConvAddPreluKernel.swift | 158 +++--- .../Operators/Kernels/ConvAddReluKernel.swift | 189 ++++--- .../Operators/Kernels/ConvBNReluKernel.swift | 157 +++--- .../Src/Operators/Kernels/ConvKernel.swift | 59 ++- .../Kernels/ConvTransposeKernel.swift | 58 ++- .../Kernels/ElementwiseAddKernel.swift | 44 +- .../Kernels/ElementwiseAddPreluKernel.swift | 56 ++- .../Src/Operators/Kernels/ExpKernel.swift | 37 +- .../Src/Operators/Kernels/FetchKernel.swift | 46 +- .../Src/Operators/Kernels/FlattenKernel.swift | 90 ++-- .../Operators/Kernels/LeakyReluKernel.swift | 39 +- .../Kernels/MulticlassNMSKernel.swift | 53 +- .../Kernels/NearestInterpKernel.swift | 39 +- .../Src/Operators/Kernels/PoolKernel.swift | 42 +- .../Src/Operators/Kernels/PreluKernel.swift | 52 +- .../Operators/Kernels/PriorBoxKernel.swift | 64 +-- .../Src/Operators/Kernels/Relu6Kernel.swift | 39 +- .../Src/Operators/Kernels/ReluKernel.swift | 37 +- .../Src/Operators/Kernels/ReshapeKernel.swift | 58 +-- .../Kernels/ResizeBilinearKernel.swift | 40 +- .../Src/Operators/Kernels/Scale.swift | 8 +- .../Src/Operators/Kernels/ScaleOpKernel.swift | 69 +-- .../Src/Operators/Kernels/ShapeKernel.swift | 14 +- .../Src/Operators/Kernels/SigmoidKernel.swift | 37 +- .../Src/Operators/Kernels/SliceKernel.swift | 42 +- .../Src/Operators/Kernels/SoftmaxKernel.swift | 39 +- .../Src/Operators/Kernels/SplitKernel.swift | 47 +- .../Kernels/Texture2DTo2DArrayKernel.swift | 32 +- .../Operators/Kernels/TransposeKernel.swift | 44 +- .../Src/Operators/LeakyReluOp.swift | 24 +- .../Src/Operators/MulticlassNMSOp.swift | 36 +- .../Src/Operators/NearestInterpOp.swift | 39 +- .../paddle-mobile/Src/Operators/PoolOp.swift | 35 +- .../paddle-mobile/Src/Operators/PreluOp.swift | 30 +- .../Src/Operators/PriorBoxOp.swift | 78 +-- .../paddle-mobile/Src/Operators/Relu6Op.swift | 24 +- .../paddle-mobile/Src/Operators/ReluOp.swift | 20 +- .../Src/Operators/ReshapeOp.swift | 73 ++- .../Src/Operators/ResizeBilinearOp.swift | 21 +- .../paddle-mobile/Src/Operators/ScaleOp.swift | 28 +- .../paddle-mobile/Src/Operators/ShapeOp.swift | 14 +- .../Src/Operators/SigmoidOp.swift | 20 +- .../paddle-mobile/Src/Operators/SliceOp.swift | 42 +- .../Src/Operators/SoftmaxOp.swift | 32 +- .../paddle-mobile/Src/Operators/SplitOp.swift | 46 +- .../Src/Operators/TransposeOp.swift | 20 +- .../paddle-mobile/Src/Program/Attribute.swift | 4 +- .../Src/Program/MemoryOptimze.swift | 197 ++++++++ .../Src/Program/PMBlockDesc.swift | 4 +- .../paddle-mobile/Src/Program/PMOpDesc.swift | 6 +- .../Src/Program/PMProgramDesc.swift | 4 +- .../paddle-mobile/Src/Program/PMVarDesc.swift | 7 +- .../Src/Program/ProgramOptimize.swift | 30 +- .../Src/Program/TensorDesc.swift | 15 +- 127 files changed, 4454 insertions(+), 2590 deletions(-) create mode 100644 metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.pbxproj create mode 100644 metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/xcshareddata/xcschemes/PaddleMobileTest.xcscheme create mode 100644 metal/PaddleMobileTest/PaddleMobileTest/AppDelegate.swift create mode 100644 metal/PaddleMobileTest/PaddleMobileTest/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 metal/PaddleMobileTest/PaddleMobileTest/Assets.xcassets/Contents.json create mode 100644 metal/PaddleMobileTest/PaddleMobileTest/Base.lproj/LaunchScreen.storyboard create mode 100644 metal/PaddleMobileTest/PaddleMobileTest/Base.lproj/Main.storyboard create mode 100644 metal/PaddleMobileTest/PaddleMobileTest/Info.plist create mode 100644 metal/PaddleMobileTest/PaddleMobileTest/TestViewController.swift create mode 100644 metal/PaddleMobileTest/PaddleMobileTest/ViewController.swift create mode 100644 metal/paddle-mobile/paddle-mobile/Src/Framework/Utils.swift create mode 100644 metal/paddle-mobile/paddle-mobile/Src/Program/MemoryOptimze.swift diff --git a/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift b/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift index c0814601bb..f28c3137c8 100644 --- a/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift +++ b/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift @@ -15,7 +15,7 @@ import Foundation import paddle_mobile -public class MobileNet: Net{ +public class MobileNet: Net { class MobilenetPreProccess: CusomKernel { init(device: MTLDevice) { let s = Shape.init(inWidth: 224, inHeight: 224, inChannel: 3) @@ -31,12 +31,12 @@ public class MobileNet: Net{ 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)") + } else { + print("no file called \(fileName)") } } subscript(index: Int) -> String { - return contents[index] + return index < contents.count ? contents[index] : "" } } @@ -52,15 +52,24 @@ public class MobileNet: Net{ return s.joined(separator: "\n") } - override public init(device: MTLDevice) { + override public init(device: MTLDevice) throws { super.init(device: device) except = 0 - modelPath = Bundle.main.path(forResource: "mobilenet_model", ofType: nil) ?! "model null" - paramPath = Bundle.main.path(forResource: "mobilenet_params", ofType: nil) ?! "para null" + guard let modelPath = Bundle.main.path(forResource: "mobilenet_model", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null") + } + self.modelPath = modelPath + guard let paramPath = Bundle.main.path(forResource: "mobilenet_params", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "para null") + } + self.paramPath = paramPath preprocessKernel = MobilenetPreProccess.init(device: device) inputDim = Dim.init(inDim: [1, 224, 224, 3]) metalLoadMode = .LoadMetalInCustomMetalLib - metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") + guard let metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "metallib null") + } + self.metalLibPath = metalLibPath useMPS = true } } diff --git a/metal/MobileNetDemo/MobileNetDemo/ViewController.swift b/metal/MobileNetDemo/MobileNetDemo/ViewController.swift index a0d69c5c06..675265b2a4 100644 --- a/metal/MobileNetDemo/MobileNetDemo/ViewController.swift +++ b/metal/MobileNetDemo/MobileNetDemo/ViewController.swift @@ -38,7 +38,7 @@ class ViewController: UIViewController { print(resutText) self.resultTextView.text = resutText } else { - fatalError(" load error ") + print("load fail!!!") } } @@ -81,7 +81,8 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { picker.dismiss(animated: true){[weak self] in guard let sSelf = self, let image = info["UIImagePickerControllerOriginalImage"] as? UIImage else { - fatalError("no image") + print("no image!!!") + return } sSelf.selectImageView.image = image sSelf.runner.getTexture(image: image.cgImage!, getTexture: { (texture) in diff --git a/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.pbxproj b/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..0bbe4140e0 --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.pbxproj @@ -0,0 +1,457 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 63B1E033193F615BEBD58F0A /* Pods_PaddleMobileTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBD7FB4D751917F7F9CCDED6 /* Pods_PaddleMobileTest.framework */; }; + A7138A8522C4AE8D00DE0BD3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7138A8422C4AE8D00DE0BD3 /* AppDelegate.swift */; }; + A7138A8722C4AE8D00DE0BD3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7138A8622C4AE8D00DE0BD3 /* ViewController.swift */; }; + A7138A8A22C4AE8E00DE0BD3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A7138A8822C4AE8E00DE0BD3 /* Main.storyboard */; }; + A7138A8C22C4AE9100DE0BD3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A7138A8B22C4AE9100DE0BD3 /* Assets.xcassets */; }; + A7138A8F22C4AE9100DE0BD3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A7138A8D22C4AE9100DE0BD3 /* LaunchScreen.storyboard */; }; + A7138A9722C4E36200DE0BD3 /* TestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7138A9622C4E36100DE0BD3 /* TestViewController.swift */; }; + A73E3FBC22CA330F00860CFD /* yolo_params_v3_16 in Resources */ = {isa = PBXBuildFile; fileRef = A73E3FBA22CA330E00860CFD /* yolo_params_v3_16 */; }; + A73E3FBD22CA330F00860CFD /* yolo_model_v3_16 in Resources */ = {isa = PBXBuildFile; fileRef = A73E3FBB22CA330E00860CFD /* yolo_model_v3_16 */; }; + A759D07822E6B96500570128 /* paddle-mobile-metallib.metallib in Resources */ = {isa = PBXBuildFile; fileRef = A759D07722E6B96500570128 /* paddle-mobile-metallib.metallib */; }; + A759D07A22E6BAFB00570128 /* paddle_mobile.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A759D07922E6BAFB00570128 /* paddle_mobile.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + A7138A8122C4AE8D00DE0BD3 /* PaddleMobileTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PaddleMobileTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A7138A8422C4AE8D00DE0BD3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + A7138A8622C4AE8D00DE0BD3 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + A7138A8922C4AE8E00DE0BD3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + A7138A8B22C4AE9100DE0BD3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + A7138A8E22C4AE9100DE0BD3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + A7138A9022C4AE9100DE0BD3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A7138A9622C4E36100DE0BD3 /* TestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestViewController.swift; sourceTree = ""; }; + A73E3FBA22CA330E00860CFD /* yolo_params_v3_16 */ = {isa = PBXFileReference; lastKnownFileType = file; name = yolo_params_v3_16; path = ../../../../../Documents/paddlemobiletest/yolo_params_v3_16; sourceTree = ""; }; + A73E3FBB22CA330E00860CFD /* yolo_model_v3_16 */ = {isa = PBXFileReference; lastKnownFileType = file; name = yolo_model_v3_16; path = ../../../../../Documents/paddlemobiletest/yolo_model_v3_16; sourceTree = ""; }; + A759D07722E6B96500570128 /* paddle-mobile-metallib.metallib */ = {isa = PBXFileReference; lastKnownFileType = "archive.metal-library"; name = "paddle-mobile-metallib.metallib"; path = "../../../../../Library/Developer/Xcode/DerivedData/paddle-mobile-ahygfxrimvxpabekluyjeefybtnn/Build/Products/Release-iphoneos/paddle-mobile-metallib.metallib"; sourceTree = ""; }; + A759D07922E6BAFB00570128 /* paddle_mobile.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = paddle_mobile.framework; path = "../../../../../Library/Developer/Xcode/DerivedData/paddle-mobile-ahygfxrimvxpabekluyjeefybtnn/Build/Products/Debug-iphoneos/paddle_mobile.framework"; sourceTree = ""; }; + B9E5E71FB1F45F0539BC30B8 /* Pods-PaddleMobileTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PaddleMobileTest.release.xcconfig"; path = "Target Support Files/Pods-PaddleMobileTest/Pods-PaddleMobileTest.release.xcconfig"; sourceTree = ""; }; + BB4F668F51949D6F7E88641F /* Pods-PaddleMobileTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PaddleMobileTest.debug.xcconfig"; path = "Target Support Files/Pods-PaddleMobileTest/Pods-PaddleMobileTest.debug.xcconfig"; sourceTree = ""; }; + CBD7FB4D751917F7F9CCDED6 /* Pods_PaddleMobileTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PaddleMobileTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + A7138A7E22C4AE8D00DE0BD3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A759D07A22E6BAFB00570128 /* paddle_mobile.framework in Frameworks */, + 63B1E033193F615BEBD58F0A /* Pods_PaddleMobileTest.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3D35D3608D9C641A0B411ECF /* Frameworks */ = { + isa = PBXGroup; + children = ( + CBD7FB4D751917F7F9CCDED6 /* Pods_PaddleMobileTest.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 467B36527BB8321ECB123A29 /* Pods */ = { + isa = PBXGroup; + children = ( + BB4F668F51949D6F7E88641F /* Pods-PaddleMobileTest.debug.xcconfig */, + B9E5E71FB1F45F0539BC30B8 /* Pods-PaddleMobileTest.release.xcconfig */, + ); + name = Pods; + path = ../Pods; + sourceTree = ""; + }; + A7138A7822C4AE8D00DE0BD3 = { + isa = PBXGroup; + children = ( + A73E3FBB22CA330E00860CFD /* yolo_model_v3_16 */, + A73E3FBA22CA330E00860CFD /* yolo_params_v3_16 */, + A759D07722E6B96500570128 /* paddle-mobile-metallib.metallib */, + A759D07922E6BAFB00570128 /* paddle_mobile.framework */, + A7138A8322C4AE8D00DE0BD3 /* PaddleMobileTest */, + A7138A8222C4AE8D00DE0BD3 /* Products */, + 467B36527BB8321ECB123A29 /* Pods */, + 3D35D3608D9C641A0B411ECF /* Frameworks */, + ); + sourceTree = ""; + }; + A7138A8222C4AE8D00DE0BD3 /* Products */ = { + isa = PBXGroup; + children = ( + A7138A8122C4AE8D00DE0BD3 /* PaddleMobileTest.app */, + ); + name = Products; + sourceTree = ""; + }; + A7138A8322C4AE8D00DE0BD3 /* PaddleMobileTest */ = { + isa = PBXGroup; + children = ( + A7138A8422C4AE8D00DE0BD3 /* AppDelegate.swift */, + A7138A8622C4AE8D00DE0BD3 /* ViewController.swift */, + A7138A8822C4AE8E00DE0BD3 /* Main.storyboard */, + A7138A8B22C4AE9100DE0BD3 /* Assets.xcassets */, + A7138A8D22C4AE9100DE0BD3 /* LaunchScreen.storyboard */, + A7138A9022C4AE9100DE0BD3 /* Info.plist */, + A7138A9622C4E36100DE0BD3 /* TestViewController.swift */, + ); + path = PaddleMobileTest; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A7138A8022C4AE8D00DE0BD3 /* PaddleMobileTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = A7138A9322C4AE9100DE0BD3 /* Build configuration list for PBXNativeTarget "PaddleMobileTest" */; + buildPhases = ( + 896B772D5979550252A5A335 /* [CP] Check Pods Manifest.lock */, + A7138A7D22C4AE8D00DE0BD3 /* Sources */, + A7138A7E22C4AE8D00DE0BD3 /* Frameworks */, + A7138A7F22C4AE8D00DE0BD3 /* Resources */, + 0B913BBB59E1AE207CEE0A43 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PaddleMobileTest; + productName = PaddleMobileTest; + productReference = A7138A8122C4AE8D00DE0BD3 /* PaddleMobileTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A7138A7922C4AE8D00DE0BD3 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1020; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Li,Jian(MMS)"; + TargetAttributes = { + A7138A8022C4AE8D00DE0BD3 = { + CreatedOnToolsVersion = 10.2.1; + }; + }; + }; + buildConfigurationList = A7138A7C22C4AE8D00DE0BD3 /* Build configuration list for PBXProject "PaddleMobileTest" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = A7138A7822C4AE8D00DE0BD3; + productRefGroup = A7138A8222C4AE8D00DE0BD3 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A7138A8022C4AE8D00DE0BD3 /* PaddleMobileTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A7138A7F22C4AE8D00DE0BD3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A7138A8F22C4AE9100DE0BD3 /* LaunchScreen.storyboard in Resources */, + A7138A8C22C4AE9100DE0BD3 /* Assets.xcassets in Resources */, + A73E3FBD22CA330F00860CFD /* yolo_model_v3_16 in Resources */, + A759D07822E6B96500570128 /* paddle-mobile-metallib.metallib in Resources */, + A73E3FBC22CA330F00860CFD /* yolo_params_v3_16 in Resources */, + A7138A8A22C4AE8E00DE0BD3 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0B913BBB59E1AE207CEE0A43 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-PaddleMobileTest/Pods-PaddleMobileTest-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework", + "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PaddleMobileTest/Pods-PaddleMobileTest-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 896B772D5979550252A5A335 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-PaddleMobileTest-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A7138A7D22C4AE8D00DE0BD3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A7138A8722C4AE8D00DE0BD3 /* ViewController.swift in Sources */, + A7138A9722C4E36200DE0BD3 /* TestViewController.swift in Sources */, + A7138A8522C4AE8D00DE0BD3 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + A7138A8822C4AE8E00DE0BD3 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A7138A8922C4AE8E00DE0BD3 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + A7138A8D22C4AE9100DE0BD3 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + A7138A8E22C4AE9100DE0BD3 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + A7138A9122C4AE9100DE0BD3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + A7138A9222C4AE9100DE0BD3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + A7138A9422C4AE9100DE0BD3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BB4F668F51949D6F7E88641F /* Pods-PaddleMobileTest.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = A798K58VVL; + INFOPLIST_FILE = PaddleMobileTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + "\"Alamofire\"", + "-framework", + "\"Protobuf\"", + "-all_load", + ); + PRODUCT_BUNDLE_IDENTIFIER = mutouren.PaddleMobileTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + A7138A9522C4AE9100DE0BD3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B9E5E71FB1F45F0539BC30B8 /* Pods-PaddleMobileTest.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = A798K58VVL; + INFOPLIST_FILE = PaddleMobileTest/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + "\"Alamofire\"", + "-framework", + "\"Protobuf\"", + "-all_load", + ); + PRODUCT_BUNDLE_IDENTIFIER = mutouren.PaddleMobileTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A7138A7C22C4AE8D00DE0BD3 /* Build configuration list for PBXProject "PaddleMobileTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A7138A9122C4AE9100DE0BD3 /* Debug */, + A7138A9222C4AE9100DE0BD3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A7138A9322C4AE9100DE0BD3 /* Build configuration list for PBXNativeTarget "PaddleMobileTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A7138A9422C4AE9100DE0BD3 /* Debug */, + A7138A9522C4AE9100DE0BD3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = A7138A7922C4AE8D00DE0BD3 /* Project object */; +} diff --git a/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..b1e7d0c915 --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/xcshareddata/xcschemes/PaddleMobileTest.xcscheme b/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/xcshareddata/xcschemes/PaddleMobileTest.xcscheme new file mode 100644 index 0000000000..99841044fd --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest.xcodeproj/xcshareddata/xcschemes/PaddleMobileTest.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/metal/PaddleMobileTest/PaddleMobileTest/AppDelegate.swift b/metal/PaddleMobileTest/PaddleMobileTest/AppDelegate.swift new file mode 100644 index 0000000000..b069c4d949 --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// PaddleMobileTest +// +// Created by Li,Jian(MMS) on 2019/6/27. +// Copyright © 2019 Li,Jian(MMS). All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/metal/PaddleMobileTest/PaddleMobileTest/Assets.xcassets/AppIcon.appiconset/Contents.json b/metal/PaddleMobileTest/PaddleMobileTest/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..d8db8d65fd --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/metal/PaddleMobileTest/PaddleMobileTest/Assets.xcassets/Contents.json b/metal/PaddleMobileTest/PaddleMobileTest/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..da4a164c91 --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/metal/PaddleMobileTest/PaddleMobileTest/Base.lproj/LaunchScreen.storyboard b/metal/PaddleMobileTest/PaddleMobileTest/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..bfa3612941 --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/metal/PaddleMobileTest/PaddleMobileTest/Base.lproj/Main.storyboard b/metal/PaddleMobileTest/PaddleMobileTest/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..27f03617d8 --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest/Base.lproj/Main.storyboard @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/metal/PaddleMobileTest/PaddleMobileTest/Info.plist b/metal/PaddleMobileTest/PaddleMobileTest/Info.plist new file mode 100644 index 0000000000..23664ef868 --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest/Info.plist @@ -0,0 +1,52 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSCameraUsageDescription + need camera + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/metal/PaddleMobileTest/PaddleMobileTest/TestViewController.swift b/metal/PaddleMobileTest/PaddleMobileTest/TestViewController.swift new file mode 100644 index 0000000000..d8d4c554ae --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest/TestViewController.swift @@ -0,0 +1,466 @@ +// +// TestViewController.swift +// PaddleMobileTest +// +// Created by Li,Jian(MMS) on 2019/6/27. +// Copyright © 2019 Li,Jian(MMS). All rights reserved. +// + +import UIKit +import Alamofire +import paddle_mobile + +class Model: CustomStringConvertible { + var name = "" + var paramsPrecision: [Int] = [0, 1] + var fusion: [Bool] = [true, false] + var useMPS: [Bool] = [true, false] + var reuseTexture: [Bool] = [true, false] + var testPerformance = true + var diffPrecision: Float = 0.1 + var varsDic: [String: [Int]] = [:] + + var description: String { + return "name: \(name)\nfusion: \(fusion)\nuseMPS:\(useMPS)\nreuseTexture:\(reuseTexture)\ntestPerformance: \(testPerformance)\ndiffPrecision: \(diffPrecision)\nvarsDesc:\(varsDic)" + } +} + +class TestModel: CustomStringConvertible, Codable { + var name: String + var paramsPrecision: Int + var fusion: Bool + var useMPS: Bool + var reuseTexture: Bool + var testPerformance: Bool + var diffPrecision: Float + var varsDic: [String: [Int]] + + init(name: String, paramsPrecision: Int, fusion: Bool, useMPS: Bool, reuseTexture: Bool, testPerformance: Bool, diffPrecision: Float, varsDic: [String: [Int]]) { + self.name = name + self.paramsPrecision = paramsPrecision + self.fusion = fusion + self.useMPS = useMPS + self.reuseTexture = reuseTexture + self.testPerformance = testPerformance + self.diffPrecision = diffPrecision + self.varsDic = varsDic + } + + var description: String { + return "name: \(name)\nparamsPrecision:\(paramsPrecision)\nfusion: \(fusion)\nuseMPS:\(useMPS)\nreuseTexture:\(reuseTexture)\ntestPerformance: \(testPerformance)\ndiffPrecision: \(diffPrecision)\nvarsDesc:\(varsDic)" + } +} + +class ModelTestResult: Codable { + var model: TestModel? + var isResultEqual = false + var performance = 0.0 + var msg = "" + var diverVarName = "" +} + +let device = MTLCreateSystemDefaultDevice()! +let commandQueue = device.makeCommandQueue()! +var timeCosts = [Double]() +var count = 0 +var totalCount = 10 + +var orderedVars: [String] = [] +var varIndex = 0 + +class TestViewController: UIViewController { + private var hostUrlStr = "" + private var testModels: [TestModel] = [] + private var testResults: [ModelTestResult] = [] + private var runner: Runner? + private var textView: UITextView! + + init(hostUrlStr: String) { + //self.hostUrlStr = "https://www.baidu.com"// + self.hostUrlStr = hostUrlStr + super.init(nibName: nil, bundle: nil) + self.title = self.hostUrlStr + } + + required init?(coder aDecoder: NSCoder) { + return nil + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + textView = UITextView(frame: self.view.bounds) + self.view.addSubview(textView) + textView.text = "hello" + textView.backgroundColor = .white + textView.isEditable = false + + let button1 = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50)) + button1.center = CGPoint(x: self.view.center.x, y: 200) + button1.addTarget(self, action: #selector(test1), for: .touchUpInside) + button1.backgroundColor = .lightGray + button1.setTitle("开始测试", for: .normal) + self.view.addSubview(button1) + } + + @objc func test1() { + getTestInfo() + } + + private func getTestInfo() { + Alamofire.request("\(hostUrlStr)/getTestInfo").validate().responseJSON { (response) in + guard response.result.isSuccess else { + self.testLog("getTestInfo request error") + return + } + guard let json = response.result.value as? [String: Any] else { + self.testLog("getTestInfo serialize error") + return + } + if let modelList = json["model_list"] as? [[String: Any]] { + self.testModels.removeAll() + for model in modelList { + guard let name = model["name"] as? String else { + self.testLog("getTestInfo fetch name error") + return + } + guard let varsDic = model["vars_dic"] as? [String: [Int]] else { + self.testLog("getTestInfo fetch vars_dic error") + return + } + let paddlemodel = Model() + paddlemodel.name = name + paddlemodel.varsDic = varsDic + if let paramsPrecision = model["params_precision"] as? [Int] { + paddlemodel.paramsPrecision = paramsPrecision + } + if let fusion = model["fusion"] as? [Bool] { + paddlemodel.fusion = fusion + } + if let useMPS = model["use_mps"] as? [Bool] { + paddlemodel.useMPS = useMPS + } + if let reuseTexture = model["reuse_texture"] as? [Bool] { + paddlemodel.reuseTexture = reuseTexture + } + if let testPerformance = model["test_performance"] as? NSNumber { + paddlemodel.testPerformance = testPerformance.boolValue + } + if let diffPrecision = model["diff_precision"] as? NSNumber { + paddlemodel.diffPrecision = diffPrecision.floatValue + } + self.testModels.append(contentsOf: self.testModelsFromModel(paddlemodel)) + } + if !self.testModels.isEmpty { + self.beginTest() + } + } + } + } + + private func beginTest() { + testResults.removeAll() + testModelOfIndex(0) + } + + private func testModelOfIndex(_ index: Int) { + guard index < self.testModels.count else { + //report + self.testLog("********test result: done") + let jsonEncoder = JSONEncoder() + let jsonData = try! jsonEncoder.encode(["results": self.testResults]) + let json = String(data: jsonData, encoding: String.Encoding.utf8) ?? "" + let data = json.data(using: .utf8)! + let jsonDic = try! JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] + Alamofire.request("\(hostUrlStr)/putTestResult", method: .post, parameters: jsonDic, encoding: JSONEncoding.default, headers: nil).validate().responseData { (response) in + guard response.result.isSuccess else { + self.testLog("puttestresult fail\ntest done") + return + } + self.testLog("puttestresult success\test done") + } + return + } + let model = self.testModels[index] + self.testLog("******begin test model: \(model)") + testModel(model) { [weak self] (testResult) in + self?.testLog("********test result: isresultequal: \(testResult.isResultEqual) msg: \(testResult.msg) performance: \(testResult.performance) s diverVar: \(testResult.diverVarName)") + self?.testResults.append(testResult) + self?.testModelOfIndex(index+1) + } + } + + private func testModel(_ model: TestModel, completion: @escaping ((ModelTestResult)->Void)) { + let testResult = ModelTestResult() + testResult.model = model + + let modelUrlStr = "\(hostUrlStr)/getFile/\(model.name)" + Alamofire.request("\(modelUrlStr)/model").validate().responseData { (response) in + guard response.result.isSuccess, let modelData = response.result.value else { + let msg = "get model \(model.name) error" + self.testLog(msg) + testResult.msg = msg + completion(testResult) + return + } + //let modelData2 = try! Data(contentsOf: URL(fileURLWithPath: Bundle.main.path(forResource: "yolo_model_v3_16", ofType: nil)!)) + let modelPtr = UnsafeMutablePointer.allocate(capacity: modelData.count) + NSData(data: modelData).getBytes(modelPtr, length: modelData.count) + Alamofire.request("\(modelUrlStr)/params/\(model.paramsPrecision)").validate().responseData(completionHandler: { (response) in + guard response.result.isSuccess, let paramsData = response.result.value else { + let msg = "get params \(model.name) error" + self.testLog(msg) + testResult.msg = msg + completion(testResult) + return + } + //let paramsData2 = try! Data(contentsOf: URL(fileURLWithPath: Bundle.main.path(forResource: "yolo_params_v3_16", ofType: nil)!)) + let paramsPtr = UnsafeMutablePointer.allocate(capacity: paramsData.count) + //paramsPtr.copyMemory(from: NSData(data: paramsData2).bytes, byteCount: paramsData2.count) + NSData(data: paramsData).getBytes(paramsPtr, length: paramsData.count) + guard let net = try? Net(device: device, inParamPointer: paramsPtr, inParamSize: paramsData.count, inModelPointer: modelPtr, inModelSize: modelData.count) else { + let msg = "init net error" + self.testLog(msg) + testResult.msg = msg + completion(testResult) + return + } + net.inputDim = Dim(inDim: [1, 1, 1, 1]) + net.paramPrecision = (model.paramsPrecision == 0) ? .Float16 : .Float32 + net.metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") + net.metalLoadMode = .LoadMetalInCustomMetalLib + guard let runner = try? Runner(inNet: net, commandQueue: commandQueue), runner.load() else { + let msg = "init runner error" + self.testLog(msg) + testResult.msg = msg + completion(testResult) + return + } + guard let feedVar = runner.feedOpOutputVarDesc(), let dims = feedVar.dims, let fetchVars = runner.fetchOpInputVarDesc(), fetchVars.count > 0 else { + let msg = "feed var nil" + self.testLog(msg) + testResult.msg = msg + completion(testResult) + return + } + let fetchVar = fetchVars[0] + net.inputDim = Dim(inDim: [dims[0], dims[2], dims[3], dims[1]]) + Alamofire.request("\(modelUrlStr)/data/\(feedVar.name.replacingOccurrences(of: "/", with: "_"))").validate().responseData(completionHandler: { (response) in + guard response.result.isSuccess, let inputData = response.result.value else { + let msg = "get var \(feedVar) error" + self.testLog(msg) + testResult.msg = msg + completion(testResult) + return + } + var fetchvarRequest = URLRequest(url: URL(string: "\(modelUrlStr)/data/\(fetchVar.name.replacingOccurrences(of: "/", with: "_"))")!) + fetchvarRequest.cachePolicy = .reloadIgnoringLocalAndRemoteCacheData + Alamofire.request(fetchvarRequest).validate().responseData(completionHandler: { (response) in + guard response.result.isSuccess, let outputData = response.result.value else { + let msg = "get var \(fetchVar) error" + self.testLog(msg) + testResult.msg = msg + completion(testResult) + return + } + self.runModel(model: model, net: net, inputData: inputData, outputData: outputData, compareCompletion: { (testResult) in + paramsPtr.deallocate() + modelPtr.deallocate() + completion(testResult) + }) + }) + }) + }) + } + } + + private func runModel(model: TestModel, net: Net, inputData: Data, outputData: Data, compareCompletion: @escaping ((_ testResult: ModelTestResult)->Void)) { + let testResult = ModelTestResult() + testResult.model = model + + net.useMPS = model.useMPS + net.paramPrecision = (model.paramsPrecision == 0) ? .Float16 : .Float32 + guard let runner = try? Runner(inNet: net, commandQueue: commandQueue), runner.load(optimizeProgram: model.fusion, optimizeMemory: model.reuseTexture) else { + let msg = "runner init or load fail" + self.testLog(msg) + testResult.msg = msg + compareCompletion(testResult) + return + } + self.runner = runner + let buffer = device.makeBuffer(length: inputData.count, options: [])! + memcpy(buffer.contents(), NSData(data: inputData).bytes, inputData.count) + runner.getTexture(inBuffer: buffer, getTexture: { (success, texture) in + if success, let texture = texture { + runner.predict(texture: texture, completion: { (success, results) in + if success, let resultHolders = results { + let resultHolder = resultHolders[0] + let outputSize = outputData.count/MemoryLayout.stride + let output = NSData(data: outputData).bytes.bindMemory(to: Float32.self, capacity: outputSize) + guard resultHolder.capacity == outputSize else { + let msg = "count not equal" + self.testLog(msg) + testResult.msg = msg + compareCompletion(testResult) + return + } + let precision = model.diffPrecision + var isResultEqual = true + var msg = "" + for i in 0.. precision && abs(a - b) / min(abs(a), abs(b)) > 0.05 { + isResultEqual = false + msg = "unequal: i: \(i) target: \(output[i]) result: \(resultHolder.result[i])" + self.testLog(msg) + testResult.msg = msg + break + } + } + testResult.isResultEqual = isResultEqual + func checkPerformance(testResult: ModelTestResult, completion: @escaping ((_ testResult: ModelTestResult)->Void)) { + if model.testPerformance { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: { + self.testPerformance(runner: runner, texture: texture, testResult: testResult, completion: completion) + }) + } else { + completion(testResult) + } + } + if isResultEqual { + checkPerformance(testResult: testResult, completion: compareCompletion) + } else { + if model.reuseTexture { + testResult.diverVarName = "can not find diver var when reusing texture" + checkPerformance(testResult: testResult, completion: compareCompletion) + } else { + self.findDivergentVar(runner: runner, testResult: testResult, completion: { (testResult) in + checkPerformance(testResult: testResult, completion: compareCompletion) + }) + } + } + return + } + }) + } else { + let msg = "get texture error" + self.testLog(msg) + testResult.msg = msg + compareCompletion(testResult) + } + }, channelNum: net.inputDim[3]) + } + + private func testPerformance(runner: Runner, texture: MTLTexture, testResult: ModelTestResult, completion: @escaping ((ModelTestResult)->Void)) { + let startTime = CFAbsoluteTimeGetCurrent() + runner.predict(texture: texture) { (success, results) in + self.testLog("!!!!!\(CFAbsoluteTimeGetCurrent()-startTime)") + if success && count > 0 { + timeCosts.append(CFAbsoluteTimeGetCurrent()-startTime) + } + count += 1 + if count < totalCount { + DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: { + self.testPerformance(runner: runner, texture: texture, testResult: testResult, completion: completion) + }) + } else { + if timeCosts.count > 0 { + var total = 0.0 + for time in timeCosts { + total += time + } + let avgTime = total / Double(timeCosts.count) + testResult.performance = avgTime + } + count = 0 + timeCosts.removeAll() + completion(testResult) + } + } + } + + private func findDivergentVar(runner: Runner, testResult: ModelTestResult, completion: @escaping ((ModelTestResult)->Void)) { + orderedVars.removeAll() + varIndex = 0 + orderedVars = runner.getAllOutputVars() + compareVars(runner: runner, model: testResult.model!) { (varName) in + testResult.diverVarName = varName + completion(testResult) + } + } + + private func compareVars(runner: Runner, model: TestModel, completion: @escaping ((_ varName: String)->Void)) { + let severVars: [String] = Array(model.varsDic.keys) + let urlString: String = "\(hostUrlStr)/getFile/\(model.name)/data" + if varIndex < orderedVars.count { + var varName = orderedVars[varIndex] + while !(severVars.contains(varName)) || runner.fetchVar(varName) == nil { + varIndex += 1 + if varIndex < orderedVars.count { + varName = orderedVars[varIndex] + } else { + break + } + } + if severVars.contains(varName) { + Alamofire.request("\(urlString)/\(varName)").validate().responseData { (response) in + varIndex += 1 + guard response.result.isSuccess, let varData = response.result.value else { + self.compareVars(runner: runner, model: model, completion: completion) + return + } + let varSize = varData.count/MemoryLayout.stride + let varTarget = NSData(data: varData).bytes.bindMemory(to: Float32.self, capacity: varSize) + let varResult = runner.fetchVar(varName)! + guard varSize == varResult.count else { + completion(varName) + return + } + let precision = model.diffPrecision + for i in 0.. precision { + completion(varName) + return + } + } + self.compareVars(runner: runner, model: model, completion: completion) + return + } + } else { + completion("") + } + } + } + + private func testModelsFromModel(_ model: Model) -> [TestModel] { + var testModels: [TestModel] = [] + for paramsPrecision in model.paramsPrecision { + for fusion in model.fusion { + for useMPS in model.useMPS { + for reuseTexture in model.reuseTexture { + let testModel = TestModel(name: model.name, paramsPrecision: paramsPrecision, fusion: fusion, useMPS: useMPS, reuseTexture: reuseTexture, testPerformance: model.testPerformance, diffPrecision: model.diffPrecision, varsDic: model.varsDic) + testModels.append(testModel) + } + } + } + } + return testModels + } + + private func testLog(_ log: String) { + DispatchQueue.main.async { + self.textView.text = self.textView.text + "\n\(log)" + DispatchQueue.main.asyncAfter(deadline: .now()+0.1) { + self.scrollTextViewToBottom(textView: self.textView) + } + } + } + + private func scrollTextViewToBottom(textView: UITextView) { + if textView.text.count > 0 { + let location = textView.text.count - 1 + let bottom = NSMakeRange(location, 1) + textView.scrollRangeToVisible(bottom) + } + } +} diff --git a/metal/PaddleMobileTest/PaddleMobileTest/ViewController.swift b/metal/PaddleMobileTest/PaddleMobileTest/ViewController.swift new file mode 100644 index 0000000000..303cb41b77 --- /dev/null +++ b/metal/PaddleMobileTest/PaddleMobileTest/ViewController.swift @@ -0,0 +1,122 @@ +// +// ViewController.swift +// PaddleMobileTest +// +// Created by Li,Jian(MMS) on 2019/6/27. +// Copyright © 2019 Li,Jian(MMS). All rights reserved. +// + +import AVFoundation +import UIKit + +class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { + var captureSession: AVCaptureSession! + var previewLayer: AVCaptureVideoPreviewLayer! + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.black + captureSession = AVCaptureSession() + + guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return } + let videoInput: AVCaptureDeviceInput + + do { + videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice) + } catch { + return + } + + if (captureSession.canAddInput(videoInput)) { + captureSession.addInput(videoInput) + } else { + failed() + return + } + + let metadataOutput = AVCaptureMetadataOutput() + + if (captureSession.canAddOutput(metadataOutput)) { + captureSession.addOutput(metadataOutput) + + metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) + metadataOutput.metadataObjectTypes = [.qr]//[.ean8, .ean13, .pdf417] + } else { + failed() + return + } + + previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) + previewLayer.frame = view.layer.bounds + previewLayer.videoGravity = .resizeAspectFill + view.layer.addSublayer(previewLayer) + + captureSession.startRunning() + } + + func failed() { + let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert) + ac.addAction(UIAlertAction(title: "OK", style: .default)) + present(ac, animated: true) + captureSession = nil + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + if (captureSession?.isRunning == false) { + captureSession.startRunning() + } + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + if (captureSession?.isRunning == true) { + captureSession.stopRunning() + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) +// let testVC = TestViewController(hostUrlStr: "http://0.0.0.0:8000") +// self.present(testVC, animated: true, completion: nil) + } + + func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { + captureSession.stopRunning() + + if let metadataObject = metadataObjects.first { + guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return } + guard let stringValue = readableObject.stringValue else { return } + AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate)) + found(code: stringValue) + } + } + + func found(code: String) { + print(code) + let testVC = TestViewController(hostUrlStr: code) + self.navigationController?.pushViewController(testVC, animated: true) + } + + func alertMsg(_ msg: String) { + let ac = UIAlertController(title: "Found!", message: msg, preferredStyle: .alert) + ac.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in + self.captureSession.startRunning() + })) + present(ac, animated: true, completion: nil) + } + + override var prefersStatusBarHidden: Bool { + return true + } + + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + return .portrait + } +} + + + diff --git a/metal/Podfile b/metal/Podfile index b3a6d8a9df..49d0396fd3 100644 --- a/metal/Podfile +++ b/metal/Podfile @@ -32,3 +32,9 @@ target 'paddle-mobile-metallib' do project 'paddle-mobile-metallib/paddle-mobile-metallib.xcodeproj' end + +target 'PaddleMobileTest' do + project 'PaddleMobileTest/PaddleMobileTest.xcodeproj' + pod 'Protobuf', '~> 3.0.0' + pod 'Alamofire' +end diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/MultiPredictViewController.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/MultiPredictViewController.swift index 8af436d779..cf5cb75a16 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/MultiPredictViewController.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/MultiPredictViewController.swift @@ -20,12 +20,12 @@ class MultiPredictViewController: UIViewController { var runner2: Runner! override func viewDidLoad() { super.viewDidLoad() - let mobileNet = MobileNet_ssd_hand.init(device: MetalHelper.shared.device) - let genet = Genet.init(device: MetalHelper.shared.device) - runner1 = Runner.init(inNet: mobileNet, commandQueue: MetalHelper.shared.queue) + let mobileNet = try! MobileNet_ssd_hand.init(device: MetalHelper.shared.device) + let genet = try! Genet.init(device: MetalHelper.shared.device) + runner1 = try! Runner.init(inNet: mobileNet, commandQueue: MetalHelper.shared.queue) let queue2 = MetalHelper.shared.device.makeCommandQueue() - runner2 = Runner.init(inNet: genet, commandQueue: MetalHelper.shared.queue) + runner2 = try! Runner.init(inNet: genet, commandQueue: MetalHelper.shared.queue) } @IBAction func predictAct(_ sender: Any) { diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/Genet.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/Genet.swift index b248e53bac..cd356f8f47 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/Genet.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/Genet.swift @@ -16,32 +16,41 @@ import Foundation import paddle_mobile public class Genet: Net { - @objc public override init(device: MTLDevice) { - super.init(device: device) - modelPath = Bundle.main.path(forResource: "genet_model", ofType: nil) ?! "model null" - paramPath = Bundle.main.path(forResource: "genet_params", ofType: nil) ?! "para null" - preprocessKernel = GenetPreProccess.init(device: device) + @objc public override init(device: MTLDevice) throws { + try super.init(device: device) + guard let modelPath = Bundle.main.path(forResource: "genet_model", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null") + } + self.modelPath = modelPath + guard let paramPath = Bundle.main.path(forResource: "genet_params", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "para null") + } + self.paramPath = paramPath + preprocessKernel = try GenetPreProccess.init(device: device) inputDim = Dim.init(inDim: [1, 128, 128, 3]) metalLoadMode = .LoadMetalInCustomMetalLib - metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") + guard let metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "metallib null") + } + self.metalLibPath = metalLibPath } - @objc override public init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) { - super.init(device: device, + @objc override public init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) throws { + try super.init(device: device, inParamPointer: inParamPointer, inParamSize: inParamSize, inModelPointer: inModelPointer, inModelSize: inModelSize) metalLoadMode = .LoadMetalInCustomMetalLib metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") - preprocessKernel = GenetPreProccess.init(device: device) + preprocessKernel = try GenetPreProccess.init(device: device) inputDim = Dim.init(inDim: [1, 128, 128, 3]) } class GenetPreProccess: CusomKernel { - init(device: MTLDevice) { + init(device: MTLDevice) throws { let s = Shape.init(inWidth: 128, inHeight: 128, inChannel: 3) - super.init(device: device, inFunctionName: "genet_preprocess", outputDim: s, metalLoadModel: .LoadMetalInDefaultLib, metalLibPath: nil) + try super.init(device: device, inFunctionName: "genet_preprocess", outputDim: s, metalLoadModel: .LoadMetalInDefaultLib, metalLibPath: nil) } } 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 608cd3180b..6fe27cf7d1 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNet.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNet.swift @@ -18,9 +18,9 @@ import paddle_mobile public class MobileNet: Net{ class MobilenetPreProccess: CusomKernel { - init(device: MTLDevice) { + init(device: MTLDevice) throws { let s = Shape.init(inWidth: 224, inHeight: 224, inChannel: 3) - super.init(device: device, inFunctionName: "mobilenet_preprocess", outputDim: s, metalLoadModel: .LoadMetalInDefaultLib, metalLibPath: nil) + try super.init(device: device, inFunctionName: "mobilenet_preprocess", outputDim: s, metalLoadModel: .LoadMetalInDefaultLib, metalLibPath: nil) } } @@ -32,12 +32,12 @@ public class MobileNet: Net{ 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)") + } else { + print("no file called \(fileName)") } } subscript(index: Int) -> String { - return contents[index] + return index < contents.count ? contents[index] : "" } } @@ -52,17 +52,24 @@ public class MobileNet: Net{ return s.joined(separator: "\n") } - override public init(device: MTLDevice) { - super.init(device: device) + override public init(device: MTLDevice) throws { + try super.init(device: device) except = 0 - modelPath = Bundle.main.path(forResource: "mobilenet_model", ofType: nil) ?! "model null" - paramPath = Bundle.main.path(forResource: "mobilenet_params", ofType: nil) ?! "para null" - // metalLoadMode = .LoadMetalInCustomMetalLib - // metalLibPath = Bundle.main.path(forResource: "PaddleMobileMetal", ofType: "metallib") ?! " can't be nil " - preprocessKernel = MobilenetPreProccess.init(device: device) + guard let modelPath = Bundle.main.path(forResource: "mobilenet_model", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null") + } + self.modelPath = modelPath + guard let paramPath = Bundle.main.path(forResource: "mobilenet_params", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "para null") + } + self.paramPath = paramPath + preprocessKernel = try MobilenetPreProccess.init(device: device) inputDim = Dim.init(inDim: [1, 224, 224, 3]) metalLoadMode = .LoadMetalInCustomMetalLib - metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") + guard let metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "metallib null") + } + self.metalLibPath = metalLibPath } } diff --git a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetCombined.swift b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetCombined.swift index 7412b41466..aeafc0f147 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetCombined.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetCombined.swift @@ -16,18 +16,26 @@ import Foundation import paddle_mobile public class MobileNetCombined: Net { - @objc public override init(device: MTLDevice) { - super.init(device: device) + @objc public override init(device: MTLDevice) throws { + try super.init(device: device) except = 0 - modelPath = Bundle.main.path(forResource: "combined_mobilenet_model_16", ofType: nil) ?! "model null" - paramPath = Bundle.main.path(forResource: "combined_mobilenet_params_16", ofType: nil) ?! "para null" + guard let modelPath = Bundle.main.path(forResource: "combined_mobilenet_model_16", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null") + } + self.modelPath = modelPath + guard let paramPath = Bundle.main.path(forResource: "combined_mobilenet_params_16", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "para null") + } + self.paramPath = paramPath inputDim = Dim.init(inDim: [1, 224, 224, 3]) metalLoadMode = .LoadMetalInCustomMetalLib - let paddleMobileMetallib = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") + guard let paddleMobileMetallib = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "metallib null") + } metalLibPath = paddleMobileMetallib useMPS = true paramPrecision = .Float16 - preprocessKernel = ScaleKernel.init(device: device, shape: Shape.init(inWidth: 224, inHeight: 224, inChannel: 3), metalLoadMode: .LoadMetalInCustomMetalLib, metalLibPath: paddleMobileMetallib) + preprocessKernel = try ScaleKernel.init(device: device, shape: Shape.init(inWidth: 224, inHeight: 224, inChannel: 3), metalLoadMode: .LoadMetalInCustomMetalLib, metalLibPath: paddleMobileMetallib) } let labels = PreWords.init(fileName: "vision_synset") @@ -40,12 +48,12 @@ public class MobileNetCombined: Net { 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)") + } else { + print("no file called \(fileName)") } } subscript(index: Int) -> String { - return contents[index] + return index < contents.count ? contents[index] : "" } } 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 38d20557d2..58081a40bf 100644 --- a/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetSSD.swift +++ b/metal/paddle-mobile-demo/paddle-mobile-demo/Net/MobileNetSSD.swift @@ -16,32 +16,41 @@ import Foundation import paddle_mobile public class MobileNet_ssd_hand: Net { - @objc public override init(device: MTLDevice) { - super.init(device: device) + @objc public override init(device: MTLDevice) throws { + try super.init(device: device) except = 2 - modelPath = Bundle.main.path(forResource: "ssd_hand_model", ofType: nil) ?! "model null" - paramPath = Bundle.main.path(forResource: "ssd_hand_params", ofType: nil) ?! "para null" + guard let modelPath = Bundle.main.path(forResource: "ssd_hand_model", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null") + } + self.modelPath = modelPath + guard let paramPath = Bundle.main.path(forResource: "ssd_hand_params", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "para null") + } + self.paramPath = paramPath metalLoadMode = .LoadMetalInCustomMetalLib - metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") - preprocessKernel = MobilenetssdPreProccess.init(device: device) + guard let metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "metallib null") + } + self.metalLibPath = metalLibPath + preprocessKernel = try MobilenetssdPreProccess.init(device: device) inputDim = Dim.init(inDim: [1, 300, 300, 3]) } - @objc override public init(device: MTLDevice,inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer inModePointer: UnsafeMutableRawPointer, inModelSize: Int) { - super.init(device:device,inParamPointer:inParamPointer,inParamSize:inParamSize,inModelPointer:inModePointer,inModelSize:inModelSize) + @objc override public init(device: MTLDevice,inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer inModePointer: UnsafeMutableRawPointer, inModelSize: Int) throws { + try super.init(device:device,inParamPointer:inParamPointer,inParamSize:inParamSize,inModelPointer:inModePointer,inModelSize:inModelSize) except = 2 modelPath = "" paramPath = "" metalLoadMode = .LoadMetalInCustomMetalLib metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") - preprocessKernel = MobilenetssdPreProccess.init(device: device) + preprocessKernel = try MobilenetssdPreProccess.init(device: device) inputDim = Dim.init(inDim: [1, 300, 300, 3]) } class MobilenetssdPreProccess: CusomKernel { - init(device: MTLDevice) { + init(device: MTLDevice) throws { let s = Shape.init(inWidth: 300, inHeight: 300, inChannel: 3) - super.init(device: device, inFunctionName: "mobilenet_ssd_preprocess", outputDim: s, metalLoadModel: .LoadMetalInDefaultLib, metalLibPath: nil) + try super.init(device: device, inFunctionName: "mobilenet_ssd_preprocess", outputDim: s, metalLoadModel: .LoadMetalInDefaultLib, metalLibPath: nil) } } @@ -50,50 +59,6 @@ public class MobileNet_ssd_hand: Net { } override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { - - // 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() - // } - // - // var scoreFormatArr: [Float32] = score.metalTexture.realNHWC(dim: (n: score.padToFourDim[0], h: score.padToFourDim[1], w: score.padToFourDim[2], c: score.padToFourDim[3])) - //// print("score: ") - //// print(scoreFormatArr.strideArray()) - //// - // var bboxArr = bbox.metalTexture.float32Array() - //// print("bbox: ") - //// print(bboxArr.strideArray()) - // - // let nmsCompute = NMSCompute.init() - // nmsCompute.scoreThredshold = 0.01 - // nmsCompute.nmsTopK = 400 - // nmsCompute.keepTopK = 200 - // nmsCompute.nmsEta = 1.0 - // nmsCompute.nmsThreshold = 0.45 - // nmsCompute.background_label = 0; - // - // nmsCompute.scoreDim = [NSNumber.init(value: score.tensorDim[0]), NSNumber.init(value: score.tensorDim[1]), NSNumber.init(value: score.tensorDim[2])] - // - // nmsCompute.bboxDim = [NSNumber.init(value: bbox.tensorDim[0]), NSNumber.init(value: bbox.tensorDim[1]), NSNumber.init(value: bbox.tensorDim[2])] - // guard let result = nmsCompute.compute(withScore: &scoreFormatArr, andBBoxs: &bboxArr) else { - // fatalError( " result error " ) - // } - // - // let output: [Float32] = result.map { $0.floatValue } - // - // - // return output - fatalError() + return [] } - - - - } 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 76feb0ecd0..3bcf793e74 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 @@ -16,30 +16,39 @@ import Foundation import paddle_mobile public class MobileNet_ssd_AR: Net { - @objc public override init(device: MTLDevice) { - super.init(device: device) + @objc public override init(device: MTLDevice) throws { + try super.init(device: device) except = 2 - modelPath = Bundle.main.path(forResource: "ar_model", ofType: nil) ?! "model null" - paramPath = Bundle.main.path(forResource: "ar_params", ofType: nil) ?! "para null" - preprocessKernel = MobilenetssdPreProccess.init(device: device) + guard let modelPath = Bundle.main.path(forResource: "ar_model", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null") + } + self.modelPath = modelPath + guard let paramPath = Bundle.main.path(forResource: "ar_params", ofType: nil) else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "para null") + } + self.paramPath = paramPath + preprocessKernel = try MobilenetssdPreProccess.init(device: device) inputDim = Dim.init(inDim: [1, 160, 160, 3]) metalLoadMode = .LoadMetalInCustomMetalLib - metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") + guard let metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "metallib null") + } + self.metalLibPath = metalLibPath } - @objc override public init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) { - super.init(device:device,inParamPointer:inParamPointer,inParamSize:inParamSize,inModelPointer:inModelPointer,inModelSize:inModelSize) + @objc override public init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) throws { + try super.init(device:device,inParamPointer:inParamPointer,inParamSize:inParamSize,inModelPointer:inModelPointer,inModelSize:inModelSize) except = 2 - preprocessKernel = MobilenetssdPreProccess.init(device: device) + preprocessKernel = try MobilenetssdPreProccess.init(device: device) inputDim = Dim.init(inDim: [1, 160, 160, 3]) metalLoadMode = .LoadMetalInCustomMetalLib metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") } class MobilenetssdPreProccess: CusomKernel { - init(device: MTLDevice) { + init(device: MTLDevice) throws { let s = Shape.init(inWidth: 160, inHeight: 160, inChannel: 3) - super.init(device: device, inFunctionName: "mobilent_ar_preprocess", outputDim: s, metalLoadModel: .LoadMetalInDefaultLib, metalLibPath: nil) + try super.init(device: device, inFunctionName: "mobilent_ar_preprocess", outputDim: s, metalLoadModel: .LoadMetalInDefaultLib, metalLibPath: nil) } } @@ -48,105 +57,6 @@ public class MobileNet_ssd_AR: Net { } override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { - fatalError() - // guard let interRes = paddleMobileRes.intermediateResults else { - // fatalError(" need have inter result ") - // } - // - // guard let scores = interRes["Scores"], scores.count > 0, let score = scores[0] as? FetchHolder else { - // fatalError(" need score ") - // } - // - // guard let bboxs = interRes["BBoxes"], bboxs.count > 0, let bbox = bboxs[0] as? FetchHolder else { - // fatalError() - // } - - // let startDate = Date.init() - - // print("scoreFormatArr: ") - //print((0.. 0 else { - throw PaddleMobileError.loaderError(message: "param file size is too small") + throw PaddleMobileError.makeError(type: .loaderError, msg: "param file size is too small") } rewind(file) } @@ -64,10 +64,10 @@ enum SupportModel: String{ } let netSupport: [SupportModel : Net] = [ - .super_resolution : SuperResolutionNet.init(device: MetalHelper.shared.device), - .yolo : YoloNet.init(device: MetalHelper.shared.device), - .mobilenet_combined : MobileNetCombined.init(device: MetalHelper.shared.device), - .mobilenet : MobileNet.init(device: MetalHelper.shared.device)] + .super_resolution : try! SuperResolutionNet.init(device: MetalHelper.shared.device), + .yolo : try! YoloNet.init(device: MetalHelper.shared.device), + .mobilenet_combined : try! MobileNetCombined.init(device: MetalHelper.shared.device), + .mobilenet : try! MobileNet.init(device: MetalHelper.shared.device)] class ViewController: UIViewController { @IBOutlet weak var resultTextView: UITextView! @@ -90,7 +90,7 @@ class ViewController: UIViewController { var threadNum = 1 @IBAction func loadAct(_ sender: Any) { - runner = Runner.init(inNet: netSupport[modelType]!, commandQueue: MetalHelper.shared.queue) + runner = try! Runner.init(inNet: netSupport[modelType]!, commandQueue: MetalHelper.shared.queue) if platform == .GPU { // let filePath = Bundle.main.path(forResource: "mingren_input_data", ofType: nil) // let fileReader = try! FileReader.init(paramPath: filePath!) @@ -109,7 +109,7 @@ class ViewController: UIViewController { let texture = convertToMTLTexture(imageBuffer: buffer.takeRetainedValue()) self.toPredictTexture = texture } else { - runner.getTexture(image: selectImage!.cgImage!) { [weak self] (texture) in + runner.getTexture(image: selectImage!.cgImage!) { [weak self] (success, texture) in let timeUse = Date.init().timeIntervalSince(beforeDate) print("get texture time use: \(timeUse)") self?.toPredictTexture = texture @@ -117,10 +117,10 @@ class ViewController: UIViewController { } } } else { - fatalError( " unsupport " ) + print( " unsupport " ) } - if runner.load() { + if runner.load(optimizeProgram: true, optimizeMemory: true) { print(" load success ! ") } else { print(" load error ! ") @@ -151,7 +151,8 @@ class ViewController: UIViewController { for i in 0.. outTexture [[texture(0)]], + uint2 gid [[thread_position_in_grid]]){ + if (gid.x >= outTexture.get_width() || + gid.y >= outTexture.get_height()) { + return; + } + + int offset = outTexture.get_width() * outTexture.get_height(); + float y0 = input[outTexture.get_width() * gid.y + gid.x + 0 * offset]; + float y1 = input[outTexture.get_width() * gid.y + gid.x + 1 * offset]; + float y2 = input[outTexture.get_width() * gid.y + gid.x + 2 * offset]; + outTexture.write(float4(y0, y1, y2, 0.0f), gid); +} + +kernel void buffer_to_texture_kernel_half_channel_3(const device float *input [[buffer(0)]], + texture2d outTexture [[texture(0)]], + uint2 gid [[thread_position_in_grid]]){ + if (gid.x >= outTexture.get_width() || + gid.y >= outTexture.get_height()) { + return; + } + + int offset = outTexture.get_width() * outTexture.get_height(); + float y0 = input[outTexture.get_width() * gid.y + gid.x + 0 * offset]; + float y1 = input[outTexture.get_width() * gid.y + gid.x + 1 * offset]; + float y2 = input[outTexture.get_width() * gid.y + gid.x + 2 * offset]; + outTexture.write(half4(y0, y1, y2, 0.0f), gid); +} + diff --git a/metal/paddle-mobile/paddle-mobile.xcodeproj/project.pbxproj b/metal/paddle-mobile/paddle-mobile.xcodeproj/project.pbxproj index 2d80f9b0a2..193e5ed613 100644 --- a/metal/paddle-mobile/paddle-mobile.xcodeproj/project.pbxproj +++ b/metal/paddle-mobile/paddle-mobile.xcodeproj/project.pbxproj @@ -33,6 +33,8 @@ 4AA1EAA2214912CD00D0F791 /* FlattenKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */; }; A73DC749227F1C7A001EB663 /* ScaleOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A73DC748227F1C7A001EB663 /* ScaleOp.swift */; }; A73DC74B227F1EDE001EB663 /* ScaleOpKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A73DC74A227F1EDE001EB663 /* ScaleOpKernel.swift */; }; + A744C89722C074AC0084C6E9 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = A744C89622C074AC0084C6E9 /* Utils.swift */; }; + A744C9B422C206E20084C6E9 /* MemoryOptimze.swift in Sources */ = {isa = PBXBuildFile; fileRef = A744C9B322C206E20084C6E9 /* MemoryOptimze.swift */; }; A7F26FDA22842EF200365D47 /* Relu6Op.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F26FD922842EF200365D47 /* Relu6Op.swift */; }; A7F26FDC2284301500365D47 /* Relu6Kernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F26FDB2284301500365D47 /* Relu6Kernel.swift */; }; C28FE02F21BA68C00054EFAC /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C28FE02C21BA68C00054EFAC /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; @@ -145,6 +147,8 @@ 4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlattenKernel.swift; sourceTree = ""; }; A73DC748227F1C7A001EB663 /* ScaleOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaleOp.swift; sourceTree = ""; }; A73DC74A227F1EDE001EB663 /* ScaleOpKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaleOpKernel.swift; sourceTree = ""; }; + A744C89622C074AC0084C6E9 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; + A744C9B322C206E20084C6E9 /* MemoryOptimze.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryOptimze.swift; sourceTree = ""; }; A7F26FD922842EF200365D47 /* Relu6Op.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Relu6Op.swift; sourceTree = ""; }; A7F26FDB2284301500365D47 /* Relu6Kernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Relu6Kernel.swift; sourceTree = ""; }; C28FE02C21BA68C00054EFAC /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; @@ -321,6 +325,7 @@ FC039B9D20E11CB20081E9F8 /* Tensor.swift */, FC039B9E20E11CB20081E9F8 /* Dim.swift */, FC9D038320E23B01000F735A /* Texture.swift */, + A744C89622C074AC0084C6E9 /* Utils.swift */, ); path = Framework; sourceTree = ""; @@ -386,6 +391,7 @@ FC039BB620E11CC20081E9F8 /* Attribute.swift */, FC039BB720E11CC20081E9F8 /* PMBlockDesc.swift */, FC4CB74A20F12C30007C0C6D /* ProgramOptimize.swift */, + A744C9B322C206E20084C6E9 /* MemoryOptimze.swift */, ); path = Program; sourceTree = ""; @@ -652,8 +658,10 @@ FC0E2DBE20EE460D009C1FAC /* BatchNormKernel.swift in Sources */, FC039BAB20E11CBC0081E9F8 /* Operator.swift in Sources */, FCD04E6A20F319EC0007374F /* SoftmaxOp.swift in Sources */, + A744C9B422C206E20084C6E9 /* MemoryOptimze.swift in Sources */, A7F26FDA22842EF200365D47 /* Relu6Op.swift in Sources */, FCBCCC612122FBDF00D94F7E /* PriorBoxKernel.swift in Sources */, + A744C89722C074AC0084C6E9 /* Utils.swift in Sources */, FCBCCC5F2122FB3B00D94F7E /* PriorBoxOp.swift in Sources */, FC9D038220E2312E000F735A /* FetchOp.swift in Sources */, FC039BBD20E11CC20081E9F8 /* Program.swift in Sources */, diff --git a/metal/paddle-mobile/paddle-mobile/API/Net.swift b/metal/paddle-mobile/paddle-mobile/API/Net.swift index aa6b43e9bf..deab4de33b 100644 --- a/metal/paddle-mobile/paddle-mobile/API/Net.swift +++ b/metal/paddle-mobile/paddle-mobile/API/Net.swift @@ -65,7 +65,7 @@ import Foundation /// 模型精度 @objc public var paramPrecision: Precision = .Float32 - @objc public init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) { + @objc public init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) throws { self.paramPointer = inParamPointer self.paramSize = inParamSize self.modelPointer = inModelPointer @@ -74,22 +74,23 @@ import Foundation super.init() } - @objc public init(device: MTLDevice) { + @objc public init(device: MTLDevice) throws { self.device = device super.init() } @objc open func resultStr(res: [ResultHolder]) -> String { - fatalError() + return "" } @objc open func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { - return paddleMobileRes.map { (gpuRes) -> ResultHolder in + let results = try? paddleMobileRes.map { (gpuRes) -> ResultHolder in guard let inResPointer = gpuRes.resultPointer else { - fatalError() + throw PaddleMobileError.makeError(type: .defaultError, msg: "resultPointer nil") } return ResultHolder.init(inResult: inResPointer, inCapacity: gpuRes.capacity, inDim: gpuRes.dim) } + return results ?? [] } open func updateProgram(program: Program) throws { diff --git a/metal/paddle-mobile/paddle-mobile/API/Runner.swift b/metal/paddle-mobile/paddle-mobile/API/Runner.swift index 9a42ba4810..882af60f79 100644 --- a/metal/paddle-mobile/paddle-mobile/API/Runner.swift +++ b/metal/paddle-mobile/paddle-mobile/API/Runner.swift @@ -35,22 +35,21 @@ import Foundation @objc public class Runner: NSObject { var program: Program? var executor: Executorable? + var memoryManager: MemoryManager? var queue: MTLCommandQueue? var textureLoader: MTKTextureLoader? public let net: Net let device: MTLDevice? - let numel: Int private static let loadLock = NSLock() private static let clearLock = NSLock() - /// 初始化函数 /// /// - Parameters: /// - inNet: 传入自定义的网络 /// - commandQueue: commandQueue - @objc public init(inNet: Net, commandQueue: MTLCommandQueue?) { + @objc public init(inNet: Net, commandQueue: MTLCommandQueue?) throws { guard inNet.inputDim.cout() == 4 else { - fatalError(" input dim count must 4 ") + throw PaddleMobileError.makeError(type: .netError, msg: "input dim count must 4") } net = inNet @@ -59,7 +58,6 @@ import Foundation if let inDevice = device { textureLoader = MTKTextureLoader.init(device: inDevice) } - numel = net.inputDim.numel() } /// load 模型, 返回 true 可进行预测,公共方法,保证线程安全 @@ -69,25 +67,31 @@ import Foundation Runner.loadLock.lock() let success = unSafeLoad() Runner.loadLock.unlock() + if !success { + clear() + } return success } /// load 模型, 返回 true 可进行预测,公共方法,保证线程安全 /// /// - Returns: load 成功或失败 - @objc public func load(optimize: Bool) -> Bool { + @objc public func load(optimizeProgram: Bool, optimizeMemory: Bool = true) -> Bool { Runner.loadLock.lock() - let success = unSafeLoad(optimize: optimize) + let success = unSafeLoad(optimizeProgram: optimizeProgram, optimizeMemory: optimizeMemory) Runner.loadLock.unlock() + if !success { + clear() + } return success } /// load 模型, 返回 true 可进行预测,不保证线程安全 /// /// - Returns: load 成功或失败 - private func unSafeLoad(optimize: Bool = true) -> Bool { + private func unSafeLoad(optimizeProgram: Bool = true, optimizeMemory: Bool = true) -> Bool { guard let inDevice = device, let inQueue = queue else { - print(" paddle mobile gpu load error, need MTLCommandQueue") + paddleMobileLog("paddle mobile gpu load error, need MTLCommandQueue", logLevel: .FatalError, callStack: Thread.callStackSymbols) return false } var loader: Loaderable @@ -101,14 +105,14 @@ import Foundation do { if let inParamPointer = net.paramPointer, let inModelPointer = net.modelPointer { guard net.paramSize > 0 && net.modelSize > 0 else { - print(" load from memory param size or model size can't 0 ") + paddleMobileLog("load from memory param size or model size can't 0", logLevel: .FatalError, callStack: Thread.callStackSymbols) return false } - program = try loader.load(device: inDevice, paramPointer: inParamPointer, paramSize: net.paramSize, modePointer: inModelPointer, modelSize: net.modelSize, optimize: optimize) + program = try loader.load(device: inDevice, paramPointer: inParamPointer, paramSize: net.paramSize, modePointer: inModelPointer, modelSize: net.modelSize, optimize: optimizeProgram) } else if let inModelPath = net.modelPath, let inParamPath = net.paramPath { - program = try loader.load(device: inDevice, modelPath: inModelPath, paraPath: inParamPath, optimize: optimize) + program = try loader.load(device: inDevice, modelPath: inModelPath, paraPath: inParamPath, optimize: optimizeProgram) } else { - print(" model pointer or model file path need be specified") + paddleMobileLog("model pointer or model file path need be specified", logLevel: .FatalError, callStack: Thread.callStackSymbols) return false } @@ -126,8 +130,15 @@ import Foundation } try net.updateProgram(program: program!) - } catch let error { - print(error) + + if optimizeMemory, #available(iOS 10.0, *) { + memoryManager = MemoryOptimize(program: program!, device: inDevice) + } else { + memoryManager = MemoryManager(program: program!, device: inDevice) + } + memoryManager?.optimizeProgramMemory() + memoryManager?.makeMetalTextures() + } catch _ { return false } return true @@ -141,8 +152,17 @@ import Foundation @objc public func predict(texture: MTLTexture, completion: @escaping ( _ success: Bool, _ result: [ResultHolder]?) -> Void) { do { guard let executor = self.executor else { - print("executor is empty") - completion(false, nil) + paddleMobileLog("executor is empty", logLevel: .FatalError, callStack: Thread.callStackSymbols) + DispatchQueue.main.async { + completion(false, nil) + } + return + } + guard texture != nil else { + paddleMobileLog("texture is nil", logLevel: .FatalError, callStack: Thread.callStackSymbols) + DispatchQueue.main.async { + completion(false, nil) + } return } try executor.predict(input: texture, dim: self.net.inputDim, completionHandle: { [weak self] (success, res) in @@ -155,9 +175,10 @@ import Foundation } completion(false, nil) }, preProcessKernle: self.net.preprocessKernel, except: self.net.except) - } catch let error { - print(error) - completion(false, nil) + } catch _ { + DispatchQueue.main.async { + completion(false, nil) + } return } } @@ -168,6 +189,7 @@ import Foundation executor?.clear() executor = nil program = nil + memoryManager = nil Runner.clearLock.unlock() } @@ -176,9 +198,14 @@ import Foundation /// - Parameters: /// - image: 输入图像 /// - getTexture: 获取 texture 回调 - @objc public func getTexture(image: CGImage, getTexture: @escaping (MTLTexture) -> Void) { - let texture = try? textureLoader?.newTexture(cgImage: image, options: [:]) ?! " texture loader error" - scaleTexture(input: texture!, complete: getTexture) + @objc public func getTexture(image: CGImage, getTexture: @escaping (Bool, MTLTexture?) -> Void) { + if let textureLoader = textureLoader, let texture = try? textureLoader.newTexture(cgImage: image, options: [:]) { + scaleTexture(input: texture, complete: getTexture) + } else { + DispatchQueue.main.async { + getTexture(false, nil) + } + } } /// 通过 buffer 获取 texture, 内部会使用GPU进行转换操作 @@ -186,27 +213,34 @@ import Foundation /// - Parameters: /// - inBuffer: 输入buffer /// - getTexture: 结果回调 - @objc public func getTexture(inBuffer: MTLBuffer, getTexture: @escaping (MTLTexture) -> Void) { + @objc public func getTexture(inBuffer: MTLBuffer, getTexture: @escaping (Bool, MTLTexture?) -> Void, channelNum: Int = 1) { guard let inQueue = queue, let inDevice = device else { - fatalError( " queue or devcie nil " ) + DispatchQueue.main.async { + getTexture(false, nil) + } + return } guard let buffer = inQueue.makeCommandBuffer() else { - fatalError( " make buffer error" ) + DispatchQueue.main.async { + getTexture(false, nil) + } + return } - let bufferToTextureKernel = BufferToTextureKernel.init(device: inDevice, outputDim: Shape.init(inWidth: net.inputDim[2], inHeight: net.inputDim[1], inChannel: net.inputDim[3]), metalLoadMode: net.metalLoadMode, metalLibPath: net.metalLibPath) do { + let bufferToTextureKernel = try BufferToTextureKernel.init(device: inDevice, outputDim: Shape.init(inWidth: net.inputDim[2], inHeight: net.inputDim[1], inChannel: net.inputDim[3]), metalLoadMode: net.metalLoadMode, metalLibPath: net.metalLibPath, channelNum: channelNum) try bufferToTextureKernel.compute(inputBuffer: inBuffer, commandBuffer: buffer) - } catch { - fatalError(" bufferToTextureKernel error ") - } - - buffer.addCompletedHandler { (buffer) in - getTexture(bufferToTextureKernel.outputTexture) + buffer.addCompletedHandler { (buffer) in + getTexture(true, bufferToTextureKernel.outputTexture) + } + buffer.commit() + } catch _ { + DispatchQueue.main.async { + getTexture(false, nil) + } + return } - - buffer.commit() } /// 更新输入维度, 针对可变长输入模型 @@ -215,41 +249,167 @@ import Foundation @objc public func updateInputDim(inDim: Dim) -> Bool { if net.inputDim != inDim { guard let inProgram = program else { - fatalError(" need load first ") + paddleMobileLog("need load first", logLevel: .FatalError, callStack: Thread.callStackSymbols) + return false } net.inputDim = inDim do { try net.updateProgram(program: inProgram) - } catch let error { - print(error) + memoryManager?.reallocMemory() + memoryManager?.makeMetalTextures() + } catch _ { return false } } return true } - public func scaleTexture(input: MTLTexture , complete: @escaping (MTLTexture) -> Void) { + public func scaleTexture(input: MTLTexture , complete: @escaping (Bool, MTLTexture?) -> Void) { guard let inQueue = queue, let inDevice = device else { - fatalError( " queue or devcie nil " ) + DispatchQueue.main.async { + complete(false, nil) + } + return } guard let buffer = inQueue.makeCommandBuffer() else { - fatalError( " make buffer error" ) + DispatchQueue.main.async { + complete(false, nil) + } + return } - let scaleKernel = ScaleKernel.init(device: inDevice, shape: Shape.init(inWidth: net.inputDim[2], inHeight: net.inputDim[1], inChannel: 3), metalLoadMode: net.metalLoadMode, metalLibPath: net.metalLibPath) - do { + let scaleKernel = try ScaleKernel.init(device: inDevice, shape: Shape.init(inWidth: net.inputDim[2], inHeight: net.inputDim[1], inChannel: 3), metalLoadMode: net.metalLoadMode, metalLibPath: net.metalLibPath) try scaleKernel.compute(inputTexuture: input, commandBuffer: buffer) - } catch let error { - print(error) - fatalError() + buffer.addCompletedHandler { (buffer) in + complete(true, scaleKernel.outputTexture) + } + buffer.commit() + } catch _ { + DispatchQueue.main.async { + complete(false, nil) + } + return } - - buffer.addCompletedHandler { (buffer) in - complete(scaleKernel.outputTexture) + } + + public func feedOpOutputVarDesc() -> PMVarDesc? { + guard let program = program else { + paddleMobileLog("need load program first") + return nil + } + var feedOp: PMOpDesc? = nil + var feedBlock: PMBlockDesc? = nil + for block in program.programDesc.blocks { + for op in block.ops { + if op.type == gFeedType { + feedOp = op + feedBlock = block + break + } + } + if feedOp != nil && feedBlock != nil{ + break + } + } + if let feedOp = feedOp, let feedBlock = feedBlock { + guard let outputKey = opInfos[gFeedType]?.outputs.first else { + return nil + } + guard let feedVarName = feedOp.outputs[outputKey]?.first else { + return nil + } + for varDesc in feedBlock.vars { + if varDesc.name == feedVarName { + return varDesc + } + } + } + return nil + } + + public func fetchOpInputVarDesc() -> [PMVarDesc]? { + guard let program = program else { + paddleMobileLog("need load program first") + return nil + } + var fetchOp: PMOpDesc? = nil + var fetchBlock: PMBlockDesc? = nil + for block in program.programDesc.blocks { + for op in block.ops { + if op.type == gFetchType { + fetchOp = op + fetchBlock = block + break + } + } + if fetchOp != nil && fetchBlock != nil{ + break + } + } + if let fetchOp = fetchOp, let fetchBlock = fetchBlock { + guard let outKey = opInfos[gFetchType]?.inputs.first else { + return nil + } + guard let fetchVarNames = fetchOp.inputs[outKey] else { + return nil + } + var varDescs: [PMVarDesc] = [] + for varName in fetchVarNames { + for varDesc in fetchBlock.vars { + if varDesc.name == varName { + varDescs.append(varDesc) + } + } + } + return varDescs + } + return nil + } + + @objc public func fetchVar(_ varName: String) -> [Float]? { + guard let value = program?.scope[varName] else { + return nil + } + if let texture = value as? Texture { + do { + if texture.transpose == [0, 2, 3, 1] { + return try texture.metalTexture?.toTensor(dim: (n: texture.padToFourDim[0], c: texture.padToFourDim[1], h: texture.padToFourDim[2], w: texture.padToFourDim[3])) + } else if texture.transpose == [0, 1, 2, 3] { + return try texture.realNHWC() + } else { + paddleMobileLog("unsupported transpose: \(texture.transpose)", logLevel: .Warning) + } + } catch _ { + return nil + } + } + return nil + } + + public func getAllOutputVars() -> [String] { + var orderedVars = [String]() + let program = self.program! + let programDesc = program.programDesc + let scope = program.scope + for block in programDesc.blocks { + var varsDic = [String: PMVarDesc]() + for varDesc in block.vars { + varsDic[varDesc.name] = varDesc + } + for op in block.ops { + let outputs = op.outputs + for dicPair in outputs { + for varName in dicPair.value { + if scope[varName] is Texture { + orderedVars.append(varName) + } + } + } + } } - buffer.commit() + return orderedVars } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Common/Errors.swift b/metal/paddle-mobile/paddle-mobile/Src/Common/Errors.swift index decb9509a6..cf2f2b00e2 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Common/Errors.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Common/Errors.swift @@ -14,6 +14,16 @@ import Foundation +public enum PaddleMobileErrorType { + case loaderError + case netError + case memoryError + case paramError + case opError + case predictError + case defaultError +} + public enum PaddleMobileError: Error{ case loaderError(message: String) case netError(message: String) @@ -21,4 +31,26 @@ public enum PaddleMobileError: Error{ case paramError(message: String) case opError(message: String) case predictError(message: String) + case defaultError(message: String) + + static public func makeError(type: PaddleMobileErrorType, msg: String, file: String = #file, line: Int = #line, function: String = #function, callStack: Array = Thread.callStackSymbols) -> PaddleMobileError { + paddleMobileLog(msg, logLevel: .FatalError, file: file, line: line, function: function, callStack: callStack) + let debugMsg = "\(msg) -file: \(file) -line: \(line) -function:\(function) -calling stack: \(callStack)" + switch type { + case .loaderError: + return PaddleMobileError.loaderError(message: debugMsg) + case .netError: + return PaddleMobileError.netError(message: debugMsg) + case .memoryError: + return PaddleMobileError.memoryError(message: debugMsg) + case .paramError: + return PaddleMobileError.paramError(message: debugMsg) + case .opError: + return PaddleMobileError.opError(message: debugMsg) + case .predictError: + return PaddleMobileError.predictError(message: debugMsg) + case .defaultError: + return PaddleMobileError.defaultError(message: debugMsg) + } + } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Common/Extensions.swift b/metal/paddle-mobile/paddle-mobile/Src/Common/Extensions.swift index 64786d0a45..f5ed25c861 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Common/Extensions.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Common/Extensions.swift @@ -14,21 +14,6 @@ import Foundation -// 自定义 ?! 如果 ?! 前的返回值为一个可选值, 则进行隐式解包, 如果有值则返回这个值, 如果为nil 则fatalError 传入的信息 -precedencegroup ExecutedOrFatalError{ - associativity: left - higherThan: AssignmentPrecedence -} -infix operator ?!: ExecutedOrFatalError -public func ?!(option: T?, excuteOrError: @autoclosure () -> String) -> T{ - if let inOpt = option { - return inOpt - }else{ - print(excuteOrError()) - fatalError(excuteOrError()) - } -} - //Lense struct Lense { let from: (A) -> B @@ -54,22 +39,16 @@ protocol CIntIndex { subscript(index: CInt) -> T { get set}; } -extension Array: CIntIndex{ +extension Array: CIntIndex { typealias T = Element subscript(index: CInt) -> T { - get{ - guard Int64(Int.max) >= Int64(index) else{ - fatalError("cint index out of Int range") - } + get { return self[Int(index)] } - set{ - guard Int64(Int.max) >= Int64(index) else{ - fatalError("cint index out of Int range") - } + set { self[Int(index)] = newValue } - + } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Common/MetalExtension.swift b/metal/paddle-mobile/paddle-mobile/Src/Common/MetalExtension.swift index a966086c8e..01aa244c90 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Common/MetalExtension.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Common/MetalExtension.swift @@ -21,85 +21,84 @@ fileprivate var paddleMobileMetalLibrary: MTLLibrary? fileprivate var customMetalLibrary: MTLLibrary? extension MTLDevice { - func defaultLibrary() -> MTLLibrary { + func defaultLibrary() throws -> MTLLibrary { if defaultMetalLibrary == nil { defaultMetalLibrary = makeDefaultLibrary() } if let inDefaultLib = defaultMetalLibrary { return inDefaultLib } else { - fatalError(" default metal libary is nil") + throw PaddleMobileError.makeError(type: .defaultError, msg: "default metal libary is nil") } } - func customLibrary(metalLibPath: String) -> MTLLibrary { + func customLibrary(metalLibPath: String) throws -> MTLLibrary { if customMetalLibrary == nil { - do { - customMetalLibrary = try makeLibrary(filepath: metalLibPath) - } catch let error { - fatalError("\(error)") - } + customMetalLibrary = try makeLibrary(filepath: metalLibPath) } if let inMetalLib = customMetalLibrary { return inMetalLib } else { - fatalError(" customlib is nil ") + throw PaddleMobileError.makeError(type: .defaultError, msg: "customlib is nil") } } - func paddleMobileLibrary() -> MTLLibrary { + func paddleMobileLibrary() throws -> MTLLibrary { if paddleMobileMetalLibrary == nil { guard let path = Bundle.init(for: Kernel.self).path(forResource: "default", ofType: "metallib") else { - fatalError("Counld't find paddle mobile library") + throw PaddleMobileError.makeError(type: .defaultError, msg: "Counld't find paddle mobile library") } do { paddleMobileMetalLibrary = try makeLibrary(filepath: path) } catch _ { - fatalError("Counld't load paddle mobile library") + throw PaddleMobileError.makeError(type: .defaultError, msg: "Counld't load paddle mobile library") } } if let inPaddleMobileLib = paddleMobileMetalLibrary { return inPaddleMobileLib } else { - fatalError("PaddleMobile metal libary is nil") + throw PaddleMobileError.makeError(type: .defaultError, msg: "PaddleMobile metal libary is nil") } } - func pipeLine(funcName: String, metalLoadMode: MetalLoadMode, metalLibPath: String?) -> MTLComputePipelineState { + func pipeLine(funcName: String, metalLoadMode: MetalLoadMode, metalLibPath: String?) throws -> MTLComputePipelineState { let useLib: MTLLibrary switch metalLoadMode { case .LoadMetalInDefaultLib: - useLib = defaultLibrary() + useLib = try defaultLibrary() case .LoadMetalInPaddleMobile: - useLib = paddleMobileLibrary() + useLib = try paddleMobileLibrary() case .LoadMetalInCustomMetalLib: - useLib = customLibrary(metalLibPath: metalLibPath ?! " can't be nil ") + guard let path = metalLibPath else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "metalibpath can not be nil") + } + useLib = try customLibrary(metalLibPath: path) default: - fatalError() + throw PaddleMobileError.makeError(type: .defaultError, msg: "metalLoadMode \(metalLoadMode) not implemented") } guard let function = useLib.makeFunction(name: funcName) else { - fatalError(" function " + funcName + " not found") + throw PaddleMobileError.makeError(type: .defaultError, msg: "function " + funcName + " not found") } do { let pipLine = try makeComputePipelineState(function: function) return pipLine } catch let error { - print(error) - fatalError("make pip line error occured : \(error)") + throw PaddleMobileError.makeError(type: .defaultError, msg: "make pip line error occured : \(error)") } - } - func makeBuffer

(value: [P]) -> MTLBuffer { - let buffer = makeBuffer(length: value.count * MemoryLayout

.size, options: MTLResourceOptions.storageModeShared) - let contents = buffer?.contents().bindMemory(to: P.self, capacity: value.count * MemoryLayout

.size) + func makeBuffer

(value: [P]) throws -> MTLBuffer { + guard let buffer = makeBuffer(length: value.count * MemoryLayout

.size, options: MTLResourceOptions.storageModeShared) else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "make buffer nil") + } + let contents = buffer.contents().bindMemory(to: P.self, capacity: value.count * MemoryLayout

.size) for i in 0..(texture: MTLTexture, cb: ([Int], P)->Void) -> Void { @@ -122,7 +121,7 @@ extension MTLDevice { } } - func texture2tensor_3

(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] { + func texture2tensor_3

(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) throws -> [P] { var tdim: [Int] = [1, 1, 1, 1] for i in 0..(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] { + func texture2tensor_2

(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) throws -> [P] { var tdim: [Int] = [1, 1, 1, 1] for i in 0..(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] { + func texture2tensor_1

(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) throws -> [P] { var tdim: [Int] = [1, 1, 1, 1] for i in 0..(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] { + func texture2tensor

(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) throws -> [P] { if dim.count == 3 { - return texture2tensor_3(texture: texture, dim: dim, transpose: transpose) + return try texture2tensor_3(texture: texture, dim: dim, transpose: transpose) } else if dim.count == 2 { - return texture2tensor_2(texture: texture, dim: dim, transpose: transpose) + return try texture2tensor_2(texture: texture, dim: dim, transpose: transpose) } else if dim.count == 1 { - return texture2tensor_1(texture: texture, dim: dim, transpose: transpose) + return try texture2tensor_1(texture: texture, dim: dim, transpose: transpose) } var tdim: [Int] = [1, 1, 1, 1] for i in 0..(value: [P], dim: [Int], transpose: [Int] = [0, 1, 2, 3], inComputePrecision: Precision = .Float32) -> MTLTexture { + func tensor2texture

(value: [P], dim: [Int], transpose: [Int] = [0, 1, 2, 3], inComputePrecision: Precision = .Float32) throws -> MTLTexture { if value.count > 0 { - assert(value.count == dim.reduce(1) { $0 * $1 }) + guard value.count == (dim.reduce(1) { $0 * $1 }) else { + throw PaddleMobileError.makeError(type: .netError, msg: "value count: \(value.count) and dim: \(dim) do not satisfy") + } } var tdim: [Int] = [1, 1, 1, 1] @@ -287,13 +305,18 @@ extension MTLDevice { var rcount: Int = (ndim[0] * ndim[3] + 3) / 4 rcount = rcount * 4 * ndim[1] * ndim[2] var nvalue: [Float32] = .init(repeating: 0.0, count: rcount) + var value32: [Float32]? if value is [Float16] { var value16 = value as! [Float16] - value32 = float16To32(input: &value16, count: value.count) + value32 = try float16To32(input: &value16, count: value.count) } else { value32 = value as? [Float32] } + guard let tmpValue32 = value32 else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "tensor2texture tensor value type not support") + } + for i0 in 0.. = UnsafeMutablePointer(mutating: nvalue) let outputP: UnsafeMutablePointer = UnsafeMutablePointer(mutating: xvalue) - float32ToFloat16(input: pointer, output: outputP, count: rcount) + try float32ToFloat16(input: pointer, output: outputP, count: rcount) let bpR = ndim[2] * 4 * 2 let bpI = ndim[1] * bpR for i in 0..(value: [P], textureWidth: Int, textureHeight: Int, arrayLength: Int) -> MTLTexture{ + func makeFloatTexture

(value: [P], textureWidth: Int, textureHeight: Int, arrayLength: Int) -> MTLTexture { let textureDesc = MTLTextureDescriptor.init() textureDesc.width = textureWidth @@ -356,6 +375,9 @@ extension MTLDevice { if value.count >= 4{ let counts = arrayLength * 4 * textureWidth * textureHeight let pointer: UnsafeMutablePointer

= UnsafeMutablePointer

.allocate(capacity: counts * MemoryLayout

.size) + defer { + pointer.deallocate() + } for i in 0.. 0 && groups.height > 0 && groups.depth > 0 else { + throw PaddleMobileError.makeError(type: PaddleMobileErrorType.predictError, msg: "dispatch thread groups width:\(groups.width) or height:\(groups.height) or depth: \(groups.depth) must not be 0") + } setComputePipelineState(computePipline) dispatchThreadgroups(groups, threadsPerThreadgroup: threadsPerGroup) @@ -449,7 +473,7 @@ public extension MTLTexture { return fArr } - func float32Array() -> [Float32] { + func float32Array() throws -> [Float32] { if pixelFormat == .rgba32Float { let float32Array = floatArray { (f: Float32) -> Float32 in return f @@ -460,15 +484,15 @@ public extension MTLTexture { var float16Array = floatArray { (f: Float16) -> Float16 in return f } - return float16To32(input: &float16Array, count: float16Array.count) + return try float16To32(input: &float16Array, count: float16Array.count) } else { - fatalError() + throw PaddleMobileError.makeError(type: .defaultError, msg: "pixelFormat \(pixelFormat) unsupported yet") } } func logDesc(header: String = "", stridable: Bool = true) -> T? { - print(header) - print("texture: \(self)") + paddleMobileLog("\(header)") + paddleMobileLog("texture: \(self)") // let res: [(index: Int, value: T)] = stridableFloatArray(stridable: stridable) // print(res) @@ -493,7 +517,7 @@ public extension MTLTexture { } bytes.deallocate() - print(str) + paddleMobileLog(str) } } else if textureType == .type2D { var str: String = "texture 2D: " @@ -514,7 +538,7 @@ public extension MTLTexture { } } - print(str) + paddleMobileLog(str) bytes.deallocate() } return nil @@ -522,7 +546,7 @@ public extension MTLTexture { } // n c h w - dim - func toTensor(dim: (n: Int, c: Int, h: Int, w: Int)) -> [Float32] { + func toTensor(dim: (n: Int, c: Int, h: Int, w: Int)) throws -> [Float32] { var textureArray: [Float32] if pixelFormat == .rgba32Float { textureArray = floatArray { (i : Float32) -> Float32 in @@ -533,9 +557,9 @@ public extension MTLTexture { var textureFloat16Array = floatArray { (i : Float16) -> Float16 in return i } - textureArray = float16To32(input: &textureFloat16Array, count: textureFloat16Array.count) + textureArray = try float16To32(input: &textureFloat16Array, count: textureFloat16Array.count) } else { - fatalError(" 目前还不支持其他类型 ") + throw PaddleMobileError.makeError(type: .defaultError, msg: "pixelFormat \(pixelFormat) unsupported yet") } print(textureArray.count) var output: [Float32] = [] @@ -554,7 +578,7 @@ public extension MTLTexture { return output } - func realNHWC(dim: (n: Int, h: Int, w: Int, c: Int)) -> [Float32] { + func realNHWC(dim: (n: Int, h: Int, w: Int, c: Int)) throws -> [Float32] { // print("origin dim: \(dim)") // print("texture: ") // print(self) @@ -568,28 +592,27 @@ public extension MTLTexture { var textureFloat16Array = floatArray { (i : Float16) -> Float16 in return i } - textureArray = float16To32(input: &textureFloat16Array, count: textureFloat16Array.count) + textureArray = try float16To32(input: &textureFloat16Array, count: textureFloat16Array.count) } else { - fatalError(" 目前还不支持其他类型 ") + throw PaddleMobileError.makeError(type: .defaultError, msg: "pixelFormat \(pixelFormat) unsupported yet") } + let total = dim.n*dim.c*dim.h*dim.w + var output: [Float32] = Array.init(repeating: 0, count: total) - var output: [Float32] = [] - let numOfASlice = dim.h * dim.w * 4 - for h in 0.. dim.c { - for i in 0..<(4 - ((sliceIndex * 4 + 4) - dim.c)) { - let value = textureArray[sliceIndex * numOfASlice + h * dim.w * 4 + w * 4 + i] - output.append(value) - } - } else { - for i in 0..<4 { - let value = textureArray[sliceIndex * numOfASlice + h * dim.w * 4 + w * 4 + i] - output.append(value) - } - } - } + for i in 0..(header: String = "", stridable: Bool = true) -> T? { - print(header) - print("MTLBuffer: \(self) ") + paddleMobileLog(header) + paddleMobileLog("MTLBuffer: \(self) ") var str = "" - if stridable && length/MemoryLayout.stride > 1000{ - for j in stride(from: 0, to: length, by: length/MemoryLayout.stride / 100){ + if stridable && length/MemoryLayout.stride > 1000 { + for j in stride(from: 0, to: length, by: length/MemoryLayout.stride / 100) { str += " \(contents().assumingMemoryBound(to: T.self)[j])" } } else { @@ -612,7 +635,7 @@ public extension MTLBuffer { str += " \(contents().assumingMemoryBound(to: T.self)[i])" } } - print(str) + paddleMobileLog(str) return nil } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Common/PaddleMobileUnitTest.swift b/metal/paddle-mobile/paddle-mobile/Src/Common/PaddleMobileUnitTest.swift index 48f3e95331..8e28fa861e 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Common/PaddleMobileUnitTest.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Common/PaddleMobileUnitTest.swift @@ -78,11 +78,20 @@ public class PaddleMobileUnitTest { odim *= dim[i] } } - assert(detectPos >= -1) + guard detectPos >= -1 else { + print("must satisfy detectPos >= -1") + return + } if (detectPos == -1) { - assert(tensor.count == odim) + guard tensor.count == odim else { + print("must satisfy tensor.count == odim") + return + } } else { - assert(tensor.count % odim == 0) + guard tensor.count % odim == 0 else { + print("must satisfy tensor.count % odim == 0") + return + } ndim[detectPos] = tensor.count / odim } indentPrintTensor(tensor: tensor, dim: ndim, ix: dim.map { $0 * 0 }, indentLevel: 0) @@ -175,7 +184,9 @@ public class PaddleMobileUnitTest { public func testTranspose() { - let buffer = queue.makeCommandBuffer() ?! "buffer is nil" + guard let buffer = queue.makeCommandBuffer() else { + return + } // var input: [Float32] = [] // for i in 0..<72 { // input.append(Float32(i)) @@ -222,7 +233,9 @@ public class PaddleMobileUnitTest { } public func testConvAddBnRelu() { - let buffer = queue.makeCommandBuffer() ?! " buffer is nil " + guard let buffer = queue.makeCommandBuffer() else { + return + } let input: [Float32] = [ 1.0, 2.0, 3.0, 4.0, @@ -299,16 +312,16 @@ public class PaddleMobileUnitTest { let inputeTexture = device.makeFloatTexture(value: input, textureWidth: 3, textureHeight: 3, arrayLength: 1) //filter - let filterBuffer = device.makeBuffer(value: filter) + let filterBuffer = try! device.makeBuffer(value: filter) // biase - let biaseBuffer = device.makeBuffer(value: biase) + let biaseBuffer = try! device.makeBuffer(value: biase) // new scale - let newScalueBuffer = device.makeBuffer(value: newScalue) + let newScalueBuffer = try! device.makeBuffer(value: newScalue) // new biase - let newBiaseBuffer = device.makeBuffer(value: newBiase) + let newBiaseBuffer = try! device.makeBuffer(value: newBiase) //output let outputTexture = device.makeFloatTexture(value: [Float32](), textureWidth: 2, textureHeight: 2, arrayLength: 1) @@ -332,9 +345,9 @@ public class PaddleMobileUnitTest { let initContext = InitContext.init() initContext.metalLoadMode = .LoadMetalInDefaultLib - let convAddBnReluKernel = ConvAddBatchNormReluKernel.init(device: device, testParam: param, initContext: initContext) + let convAddBnReluKernel = try! ConvAddBatchNormReluKernel.init(device: device, testParam: param, initContext: initContext) - convAddBnReluKernel.test(commandBuffer: buffer, param: param) + try! convAddBnReluKernel.test(commandBuffer: buffer, param: param) buffer.addCompletedHandler { (buffer) in let _: Float32? = inputeTexture.logDesc(header: "input texture", stridable: false) diff --git a/metal/paddle-mobile/paddle-mobile/Src/Common/Tools.swift b/metal/paddle-mobile/paddle-mobile/Src/Common/Tools.swift index e7e88dd00d..9809aae9f3 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Common/Tools.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Common/Tools.swift @@ -14,30 +14,40 @@ import Foundation -func writeToLibrary(fileName: String, array: [P]) { - let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last ?! " library path get error " +func writeToLibrary(fileName: String, array: [P]) throws { + guard let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "library path get error") + } let filePath = libraryPath + "/" + fileName let fileManager = FileManager.init() fileManager.createFile(atPath: filePath, contents: nil, attributes: nil) - let fileHandler = FileHandle.init(forWritingAtPath: filePath) ?! " file handler nil " + guard let fileHandler = FileHandle.init(forWritingAtPath: filePath) else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "file handler nil") + } let data = Data.init(buffer: UnsafeBufferPointer.init(start: array, count: array.count)) fileHandler.write(data) fileHandler.closeFile() } -public func writeToLibrary(fileName: String, buffer: UnsafeBufferPointer

) { - let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last ?! " library path get error " +public func writeToLibrary(fileName: String, buffer: UnsafeBufferPointer

) throws { + guard let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "library path get error") + } let filePath = libraryPath + "/" + fileName let fileManager = FileManager.init() fileManager.createFile(atPath: filePath, contents: nil, attributes: nil) - let fileHandler = FileHandle.init(forWritingAtPath: filePath) ?! " file handler nil " + guard let fileHandler = FileHandle.init(forWritingAtPath: filePath) else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "file handler nil") + } let data = Data.init(buffer: buffer) fileHandler.write(data) fileHandler.closeFile() } -func createFile(fileName: String) -> String { - let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last ?! " library path get error " +func createFile(fileName: String) throws -> String { + guard let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "library path get error") + } let filePath = libraryPath + "/" + fileName let fileManager = FileManager.init() fileManager.createFile(atPath: filePath, contents: nil, attributes: nil) diff --git a/metal/paddle-mobile/paddle-mobile/Src/Common/Types.swift b/metal/paddle-mobile/paddle-mobile/Src/Common/Types.swift index bac3f3ed91..cd20db37de 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Common/Types.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Common/Types.swift @@ -24,7 +24,7 @@ public protocol SummableMultipliable: Equatable { public protocol PrecisionProtocol: SummableMultipliable{ // init(inFloat: Float32) // init(inFloat16: Float16) - init(_ inP: P) + init(_ inP: P) throws static var bitSize: UInt { get } static func initializeValue() -> Self static var precisionType: Precision { get } @@ -41,36 +41,21 @@ extension Float16: PrecisionProtocol { return 0 } - public init

(_ inP: P) where P : PrecisionProtocol { + public init

(_ inP: P) throws where P : PrecisionProtocol { switch P.precisionType { case .Float32: - fatalError() + throw PaddleMobileError.makeError(type: .defaultError, msg: "Float16 can not be initialized from Float32") + case .Float16: self = inP as! Int16 default: - fatalError() + throw PaddleMobileError.makeError(type: .defaultError, msg: "Float16 must be initialized from Float16") } - // - // fatalError() - // if P.bitSize == Float32.bitSize { - // self = Float16(inFloat: inP as! Float32) - // } else if P.bitSize == Float16.bitSize { - // self = inP as! Float16 - // } else { - // fatalError() - // } } public static var bitSize: UInt { return 16 } - - // public init(inFloat16: Float16) { - // self = inFloat16 - // } - // public init(inFloat: Float32) { - // self = Int16(inFloat) - // } } extension Float32: PrecisionProtocol { @@ -83,56 +68,41 @@ extension Float32: PrecisionProtocol { return 0.0 } - public init

(_ inP: P) where P : PrecisionProtocol { + public init

(_ inP: P) throws where P : PrecisionProtocol { switch P.precisionType { case .Float32: self = inP as! Float32 case .Float16: self = Float32.init(Int32.init(inP as! Int16)) default: - fatalError() + throw PaddleMobileError.makeError(type: .defaultError, msg: "Float32 must be initialized from Float16 or Float32") } - // if P.bitSize == Float32.bitSize { - // self = inP as! Float32 - // } else if P.bitSize == Float16.bitSize { - // self = Float32.init(inP as! Float16) - // } else { - // fatalError() - // } } - // public init(inFloat: Float32) { - // self = inFloat - // } - // - // public init(inFloat16: Float16) { - // self = Float32.init(inFloat16) - // } - // public static var bitSize: UInt { return 32 } } -public func float32ToFloat16(input: UnsafeMutablePointer, output: UnsafeMutableRawPointer, count: Int) { +public func float32ToFloat16(input: UnsafeMutablePointer, output: UnsafeMutableRawPointer, count: Int) throws { var float32Buffer = vImage_Buffer(data: input, height: 1, width: UInt(count), rowBytes: count * 4) var float16buffer = vImage_Buffer(data: output, height: 1, width: UInt(count), rowBytes: count * 2) guard vImageConvert_PlanarFtoPlanar16F(&float32Buffer, &float16buffer, 0) == kvImageNoError else { - fatalError(" float 32 to float 16 error ! ") + throw PaddleMobileError.makeError(type: .defaultError, msg: "float 32 to float 16 error!") } } -public func float16To32(input: UnsafeMutablePointer, count: Int) -> [Float32] { +public func float16To32(input: UnsafeMutablePointer, count: Int) throws -> [Float32] { var output = Array.init(repeating: 0.0, count: count) - float16to32(input: input, output: &output, count: count) + try float16to32(input: input, output: &output, count: count) return output } -public func float16to32(input: UnsafeMutablePointer, output: UnsafeMutablePointer, count: Int) { +public func float16to32(input: UnsafeMutablePointer, output: UnsafeMutablePointer, count: Int) throws { var bufferFloat16 = vImage_Buffer(data: input, height: 1, width: UInt(count), rowBytes: count * 2) var bufferFloat32 = vImage_Buffer(data: output, height: 1, width: UInt(count), rowBytes: count * 4) if vImageConvert_Planar16FtoPlanarF(&bufferFloat16, &bufferFloat32, 0) != kvImageNoError { - fatalError(" convert float16 to float32 error") + throw PaddleMobileError.makeError(type: .defaultError, msg: "convert float16 to float32 error") } } @@ -229,9 +199,9 @@ public class FetchHolder: Variant { resultBuffer = device.makeBuffer(length: paddedCapacity * 4, options: []) } - var result: UnsafeMutablePointer { + var result: UnsafeMutablePointer? { guard let inResultBuffer = resultBuffer else { - fatalError() + return nil } return inResultBuffer.contents().bindMemory(to: Float32.self, capacity: paddedCapacity) } @@ -240,16 +210,14 @@ public class FetchHolder: Variant { extension FetchHolder: CustomStringConvertible, CustomDebugStringConvertible { public var description: String { - fatalError() + return "FetchHolder: dim \(dim) capacity \(capacity) paddedCapacity \(paddedCapacity)" // return "\(result)" } public var debugDescription: String { - fatalError() + return "FetchHolder: dim \(dim) capacity \(capacity) paddedCapacity \(paddedCapacity)" // return "\(result)" } - - } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Framework/Dim.swift b/metal/paddle-mobile/paddle-mobile/Src/Framework/Dim.swift index 77b67bf16c..0867e1b6c5 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Framework/Dim.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Framework/Dim.swift @@ -49,7 +49,8 @@ import Foundation dims.swapAt(index1, index2) } - private override init(){ - fatalError() + private override init() { + dims = [] + super.init() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Framework/Executor.swift b/metal/paddle-mobile/paddle-mobile/Src/Framework/Executor.swift index 8ddcf5f555..83f84baa45 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Framework/Executor.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Framework/Executor.swift @@ -36,7 +36,7 @@ var isTest = false } public override var description: String { - fatalError() + return "" } } @@ -65,12 +65,8 @@ public class Executor: Executorable{ //block.ops.count for i in 0...shared.creat(device: inDevice, opDesc: opDesc, scope: inProgram.scope, initContext: initContext) - ops.append(op) - } catch let error { - throw error - } + let op = try OpCreator

.shared.creat(device: inDevice, opDesc: opDesc, scope: inProgram.scope, initContext: initContext) + ops.append(op) } } } @@ -79,21 +75,17 @@ public class Executor: Executorable{ inflightSemaphore.wait() guard isValid else { inflightSemaphore.signal() - throw PaddleMobileError.predictError(message: "Executor is cleared and invalid") + throw PaddleMobileError.makeError(type: .predictError, msg: "Executor is cleared and invalid") } guard let buffer = queue.makeCommandBuffer() else { inflightSemaphore.signal() - throw PaddleMobileError.predictError(message: "CommandBuffer is nil") + throw PaddleMobileError.makeError(type: .predictError, msg: "CommandBuffer is nil") } let resInput: MTLTexture if let inPre = preProcessKernle { - do { - try inPre.compute(inputTexuture: input, commandBuffer: buffer) - resInput = inPre.outputTexture - } catch let error { - throw error - } + try inPre.compute(inputTexuture: input, commandBuffer: buffer) + resInput = inPre.outputTexture } else { resInput = input } @@ -103,16 +95,12 @@ public class Executor: Executorable{ //(ops.count - except) for i in 0..<(ops.count - except) { let op = ops[i] - do { - try op.run(device: device, buffer: buffer) - } catch let error { - throw error - } + try op.run(device: device, buffer: buffer) } var outputTextures: [String : [MTLBuffer]]? if except > 0 { - ops[ops.count - except].computeMiddleResult(device: device, buffer: buffer) + try ops[ops.count - except].computeMiddleResult(device: device, buffer: buffer) outputTextures = ops[ops.count - except].inputVariant() } @@ -153,8 +141,8 @@ public class Executor: Executorable{ var resultHolder: GPUResultHolder? if except > 0 { resultHolder = GPUResultHolder.init(inDim: [], inPointer: nil, inCapacity: 0, inIntermediateResults: outputTextures) - } else if let output = SSelf.program.scope.output() as? FetchHolder { - resultHolder = GPUResultHolder.init(inDim: output.dim.dims, inPointer: output.result, inCapacity: output.capacity) + } else if let output = SSelf.program.scope.output() as? FetchHolder, let outputResult = output.result { + resultHolder = GPUResultHolder.init(inDim: output.dim.dims, inPointer: outputResult, inCapacity: output.capacity) } if let resultHolder = resultHolder { safeComplete(true, [resultHolder]) diff --git a/metal/paddle-mobile/paddle-mobile/Src/Framework/Loader.swift b/metal/paddle-mobile/paddle-mobile/Src/Framework/Loader.swift index 15707dcd56..aece176000 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Framework/Loader.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Framework/Loader.swift @@ -27,13 +27,14 @@ public class Loader: Loaderable { var nowIndex: Int init(paramPath: String) throws { guard let tmpFile = fopen(paramPath, "rb") else { - throw PaddleMobileError.loaderError(message: "open param file error" + paramPath) + throw PaddleMobileError.makeError(type: .loaderError, msg: "open param file error" + paramPath) } file = tmpFile fseek(file, 0, SEEK_END) fileSize = ftell(file) guard fileSize > 0 else { - throw PaddleMobileError.loaderError(message: "param file size is too small") + fclose(file) + throw PaddleMobileError.makeError(type: .loaderError, msg: "param file size is too small") } rewind(file) nowIndex = 0 @@ -41,7 +42,7 @@ public class Loader: Loaderable { func read(tensor: Tensor

) throws { guard nowIndex <= fileSize else { - throw PaddleMobileError.loaderError(message: "out of the file range") + throw PaddleMobileError.makeError(type: .loaderError, msg: "out of the file range") } func pointerReader(type: T.Type) -> T { @@ -78,27 +79,26 @@ public class Loader: Loaderable { var tensorDescFromParams: VarType_TensorDesc? do { tensorDescFromParams = try VarType_TensorDesc.init(data: data) - } catch let error { - print("\(error)") + } catch _ { } tensorDescCharArray.deinitialize(count: tensorDescSize) tensorDescCharArray.deallocate() repeat { guard let tensorDescFromParams = tensorDescFromParams, let dimsArrayFromParams = tensorDescFromParams.dimsArray else { - print("tensorDescFromParams is nil") + paddleMobileLog("tensorDescFromParams is nil", logLevel: .FatalError) break } if tensorDescFromParams.dimsArray_Count != dimsArrayFromParams.count { - print("dimsArray_Count not equal to tensorDescFromParams.dimsArray.count") + paddleMobileLog("dimsArray_Count not equal to tensorDescFromParams.dimsArray.count", logLevel: .FatalError) break } if tensorDescFromParams.dimsArray_Count != tensor.tensorDim.cout() { - print("dimsArray_Count not equal to tensor.tensorDim.cout()") + paddleMobileLog("dimsArray_Count not equal to tensor.tensorDim.cout()", logLevel: .FatalError) break } for i in 0..: Loaderable { let bytesRead = fread(tensor.data.pointer, 1, tensor.data.size, file) guard bytesRead == tensor.data.size else { - throw PaddleMobileError.loaderError(message: "param read size error") + throw PaddleMobileError.makeError(type: .loaderError, msg: "param read size error") } // TODO: use script to convert @@ -147,39 +147,35 @@ public class Loader: Loaderable { } func read(tensor: Tensor

) throws { - guard nowIndex <= paramSize else { - throw PaddleMobileError.loaderError(message: "out of the file range") + guard nowIndex < paramSize else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "out of the file range") } - var readerIndex: Int = 0 - func pointerReader(type: T.Type) -> T { - let ptr = UnsafeMutablePointer.allocate(capacity: MemoryLayout.size) - memcpy(ptr, paramPointer.advanced(by: Int(readerIndex)), MemoryLayout.size) + func pointerReader(type: T.Type) throws -> T { + guard nowIndex + MemoryLayout.size <= paramSize else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "must satisfy nowIndex:\(nowIndex)+MemoryLayout.size:\(MemoryLayout.size) <= paramSize:\(paramSize)") + } + let ptr = UnsafeMutablePointer.allocate(capacity: 1) + memcpy(ptr, paramPointer.advanced(by: nowIndex), MemoryLayout.size) nowIndex += MemoryLayout.size - readerIndex += MemoryLayout.size let pointee = ptr.pointee ptr.deinitialize(count: MemoryLayout.size) ptr.deallocate() - return pointee } - let _ = pointerReader(type: UInt32.self) - let lodLevel = pointerReader(type: UInt64.self) + let _ = try pointerReader(type: UInt32.self) + let lodLevel = try pointerReader(type: UInt64.self) for _ in 0...size)){ - _ = pointerReader(type: size_t.self) + _ = try pointerReader(type: size_t.self) } } - let _ = pointerReader(type: UInt32.self) - let tensorDescSize = pointerReader(type: Int32.self) - - paramPointer = paramPointer.advanced(by: Int(readerIndex)) - paramPointer = paramPointer.advanced(by: Int(tensorDescSize)) + let _ = try pointerReader(type: UInt32.self) + let tensorDescSize = try pointerReader(type: Int32.self) nowIndex += Int(tensorDescSize) - let _ = memcpy(tensor.data.pointer, paramPointer, tensor.data.size) - paramPointer = paramPointer.advanced(by: Int(tensor.data.size)) + let _ = memcpy(tensor.data.pointer, paramPointer.advanced(by: nowIndex), tensor.data.size) nowIndex += tensor.data.size } deinit { @@ -195,33 +191,33 @@ public class Loader: Loaderable { /// oc protobuf serialized Data to instance class let protoProgram = try ProgramDesc.init(data: (modelData as NSData) as Data) - let originProgramDesc = PMProgramDesc.init(protoProgram: protoProgram) - let programDesc = optimize ? ProgramOptimize

.init().optimize(originProgramDesc: originProgramDesc) : originProgramDesc + let originProgramDesc = try PMProgramDesc.init(protoProgram: protoProgram) + let programDesc = optimize ? (ProgramOptimize

.init().optimize(originProgramDesc: originProgramDesc) ?? originProgramDesc) : originProgramDesc // let programDesc = PMProgramDesc.init(protoProgram: protoProgram) if GlobalConfig.shared.debug { - print(programDesc) + paddleMobileLog("\(programDesc)") } guard programDesc.blocks.count > 0 else { - throw PaddleMobileError.loaderError(message: "count of blocks must greater than 0") + throw PaddleMobileError.makeError(type: .loaderError, msg: "count of blocks must greater than 0") } // to get feed key and fetch key let block = programDesc.blocks[0] guard let firstOp = block.ops.first, let lastOp = block.ops.last else { - throw PaddleMobileError.loaderError(message: "at least two operator") + throw PaddleMobileError.makeError(type: .loaderError, msg: "at least two operator") } guard firstOp.type == gFeedType, lastOp.type == gFetchType else { - throw PaddleMobileError.loaderError(message: "the first op is not feed or the last op is not fetch") + throw PaddleMobileError.makeError(type: .loaderError, msg: "the first op is not feed or the last op is not fetch") } guard let inputKey = opInfos[gFeedType]?.inputs.first, let outKey = opInfos[gFetchType]?.outputs.first else { - throw PaddleMobileError.loaderError(message: "the feed input key or fetch output key not found") + throw PaddleMobileError.makeError(type: .loaderError, msg: "the feed input key or fetch output key not found") } guard let feedKey = firstOp.inputs[inputKey]?.first, let fetchKey = lastOp.outputs[outKey]?.first else { - throw PaddleMobileError.loaderError(message: "feed key or fetch key not found") + throw PaddleMobileError.makeError(type: .loaderError, msg: "feed key or fetch key not found") } let scope = Scope.init(inFeedKey: feedKey, inFetchKey: fetchKey) @@ -231,7 +227,7 @@ public class Loader: Loaderable { for varDesc in block.vars { if (varDesc.type == .LodTensor) { guard let tensorDesc = varDesc.tensorDesc else { - throw PaddleMobileError.loaderError(message: "get tensor desc failed") + throw PaddleMobileError.makeError(type: .loaderError, msg: "get tensor desc failed") } if (varDesc.persistable @@ -240,28 +236,25 @@ public class Loader: Loaderable { let dimArr = tensorDesc.dims guard dimArr.count > 0 else { - throw PaddleMobileError.loaderError(message: "tensor desc dim size error") + throw PaddleMobileError.makeError(type: .loaderError, msg: "tensor desc dim size error") } let dim = Dim.init(inDim: dimArr) let tensor = Tensor

.init(inDim: dim, inLayout: tensorDesc.dataLayout, originDimsCount: tensorDesc.originDimsCount) - do { - if paraLoaderPointer != nil { - try paraLoaderPointer!.read(tensor: tensor) - } - - if paraLoader != nil { - try paraLoader!.read(tensor: tensor) - } - } catch let error { - throw error + + if paraLoaderPointer != nil { + try paraLoaderPointer!.read(tensor: tensor) + } + + if paraLoader != nil { + try paraLoader!.read(tensor: tensor) } // tensor.convert(to: DataLayout.NHWC()) // tensor.initBuffer(device: device) scope[varDesc.name] = tensor } else { let dim = Dim.init(inDim: tensorDesc.dims) - let texture = Texture.init(device: device, inDim: dim) + let texture = try Texture.init(device: device, inDim: dim) texture.originDimsCount = tensorDesc.originDimsCount scope[varDesc.name] = texture } @@ -278,35 +271,27 @@ public class Loader: Loaderable { return program } catch _ { - throw PaddleMobileError.loaderError(message: "protobuf decoder error") + throw PaddleMobileError.makeError(type: .loaderError, msg: "protobuf decoder error") } } public func load(device: MTLDevice, paramPointer: UnsafeMutableRawPointer, paramSize: Int, modePointer: UnsafeMutableRawPointer, modelSize: Int, optimize: Bool = true) throws -> Program { let modelData = Data.init(bytes:modePointer, count:modelSize) guard let paraLoader = try? ParaLoaderWithPointer.init(pPointer: paramPointer,pSize: paramSize) else { - throw PaddleMobileError.loaderError(message: "load para error") - } - do { - let program = try loadModelandParam(device, modelData, paraLoader, nil, optimize) - return program - } catch let error { - throw error + throw PaddleMobileError.makeError(type: .loaderError, msg: "load para error") } + let program = try loadModelandParam(device, modelData, paraLoader, nil, optimize) + return program } public func load(device: MTLDevice, modelPath: String, paraPath: String, optimize: Bool = true) throws -> Program { guard let modelData = try? Data.init(contentsOf: URL.init(fileURLWithPath: modelPath)) else { - throw PaddleMobileError.loaderError(message: "load " + modelPath + " failed !") + throw PaddleMobileError.makeError(type: .loaderError, msg: "load " + modelPath + " failed !") } guard let paraLoader = try? ParaLoader.init(paramPath: paraPath) else { - throw PaddleMobileError.loaderError(message: "load para error") + throw PaddleMobileError.makeError(type: .loaderError, msg: "load para error") } - do { - let program = try loadModelandParam(device, modelData, nil, paraLoader, optimize) - return program - } catch let error { - throw error - } + let program = try loadModelandParam(device, modelData, nil, paraLoader, optimize) + return program } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Framework/Tensor.swift b/metal/paddle-mobile/paddle-mobile/Src/Framework/Tensor.swift index b993850434..871e458539 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Framework/Tensor.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Framework/Tensor.swift @@ -29,15 +29,15 @@ extension Tensorial { } class DataConverter { - func convert(from: UnsafeMutablePointer

, to: UnsafeMutablePointer

, fromDim: Dim) { - fatalError(" need imp") + func convert(from: UnsafeMutablePointer

, to: UnsafeMutablePointer

, fromDim: Dim) throws { + throw PaddleMobileError.makeError(type: .memoryError, msg: "DataConverter convert need imp") } - func getToDim(fromDim: Dim, layout: DataLayout) -> (dim: Dim, layout: DataLayout) { - fatalError(" need imp") + func getToDim(fromDim: Dim, layout: DataLayout) throws -> (dim: Dim, layout: DataLayout) { + throw PaddleMobileError.makeError(type: .memoryError, msg: "DataConverter getToDim need imp") } - func capacity(fromDim: Dim) -> Int? { + func capacity(fromDim: Dim) throws -> Int? { return nil } } @@ -51,7 +51,7 @@ class MPSPointerConverter: DataConverter

{ /// - Parameters: /// - from: from pointer /// - to: to pointer - override func convert(from: UnsafeMutablePointer

, to: UnsafeMutablePointer

, fromDim: Dim) { + override func convert(from: UnsafeMutablePointer

, to: UnsafeMutablePointer

, fromDim: Dim) throws { let outputChannels = fromDim[0] let inputChannels = fromDim[1] let kernelHeight = fromDim[2] @@ -69,10 +69,10 @@ class MPSPointerConverter: DataConverter

{ } } - override func getToDim(fromDim: Dim, layout: DataLayout) -> (dim: Dim, layout: DataLayout) { + override func getToDim(fromDim: Dim, layout: DataLayout) throws -> (dim: Dim, layout: DataLayout) { if layout != DataLayout.NCHW() { - fatalError("not support") + throw PaddleMobileError.makeError(type: .memoryError, msg: "MPSPointerConverter layout other than NCHW unsupported") } let outputChannels = fromDim[0] @@ -86,13 +86,13 @@ class MPSPointerConverter: DataConverter

{ } class WinogradPointerConverter: DataConverter

{ - override func convert(from: UnsafeMutablePointer

, to: UnsafeMutablePointer

, fromDim: Dim) { + override func convert(from: UnsafeMutablePointer

, to: UnsafeMutablePointer

, fromDim: Dim) throws { let N = fromDim[0] let C = fromDim[1] let H = fromDim[2] let W = fromDim[3] if H != 3 || W != 3 { - fatalError("not support") + throw PaddleMobileError.makeError(type: .memoryError, msg: "WinogradPointerConverter convert H and W must equal to 3") } for n in 0..: DataConverter

{ func f(_ h: Int, _ w: Int) -> P { return from[fromOffset + h * W + w] } - let c05 = P(Float(0.5)) - let c025 = P(Float(0.25)) + let c05 = try P(Float(0.5)) + let c025 = try P(Float(0.25)) to[toOffset] = f(0, 0); to[toOffset + 1] = c05 * f(0, 0) to[toOffset + 1] = to[toOffset + 1] + c05 * f(0, 1) @@ -171,28 +171,28 @@ class WinogradPointerConverter: DataConverter

{ } } - override func getToDim(fromDim: Dim, layout: DataLayout) -> (dim: Dim, layout: DataLayout) { + override func getToDim(fromDim: Dim, layout: DataLayout) throws -> (dim: Dim, layout: DataLayout) { if layout != DataLayout.NCHW() { - fatalError("not support") + throw PaddleMobileError.makeError(type: .memoryError, msg: "WinogradPointerConverter getToDim only support NCHW") } let N = fromDim[0] let C = fromDim[1] let H = fromDim[2] let W = fromDim[3] if H != 3 || W != 3 { - fatalError("not support") + throw PaddleMobileError.makeError(type: .memoryError, msg: "WinogradPointerConverter getToDim H and W must equal to 3") } let toDim = Dim.init(inDim: [N, C, H + 1, W + 1]) return (dim: toDim, layout: DataLayout.NCHW()) } - override func capacity(fromDim: Dim) -> Int? { + override func capacity(fromDim: Dim) throws -> Int? { let N = fromDim[0] let C = fromDim[1] let H = fromDim[2] let W = fromDim[3] if H != 3 || W != 3 { - fatalError("not support") + throw PaddleMobileError.makeError(type: .memoryError, msg: "WinogradPointerConverter capacity H and W must equal to 3") } return N * C * (H + 1) * (W + 1) } @@ -253,12 +253,17 @@ class Tensor: Tensorial { self.originDimsCount = originDimsCount ?? inDim.cout() } - func convert(converter: DataConverter

) -> UnsafeMutablePointer

{ - let toCapacity = converter.capacity(fromDim: dim) ?? numel() + func convert(converter: DataConverter

) throws -> UnsafeMutablePointer

{ + let toCapacity = try converter.capacity(fromDim: dim) ?? numel() let to = UnsafeMutablePointer

.allocate(capacity: toCapacity) - converter.convert(from: data.pointer, to: to, fromDim: dim) + do { + try converter.convert(from: data.pointer, to: to, fromDim: dim) + } catch let error { + to.deallocate() + throw error + } data = Data.init(inCount: toCapacity, inPointer: to) - let dimAndLayout = converter.getToDim(fromDim: dim, layout: layout) + let dimAndLayout = try converter.getToDim(fromDim: dim, layout: layout) dim = dimAndLayout.dim layout = dimAndLayout.layout return to @@ -289,13 +294,13 @@ class Tensor: Tensorial { layout = to } - func initBuffer(device: MTLDevice, precision computePrecision: Precision = .Float16, padWhenOneC: Bool = false, convertToNHWC: Bool = true, withTranspose: Bool = false) { + func initBuffer(device: MTLDevice, precision computePrecision: Precision = .Float16, padWhenOneC: Bool = false, convertToNHWC: Bool = true, withTranspose: Bool = false) throws { if convertToNHWC { convert(to: DataLayout.NHWC()) } - if P.precisionType == .Float16 && computePrecision == .Float32{ - fatalError(" 不支持: 16位模型不能按照 32 位进行运算") + if P.precisionType == .Float16 && computePrecision == .Float32 { + throw PaddleMobileError.makeError(type: .predictError, msg: "Float16 model can not compute in Float32 precision") } if withTranspose { @@ -338,7 +343,7 @@ class Tensor: Tensorial { case .Float32: buffer?.contents().copyMemory(from: data.pointer, byteCount: count * MemoryLayout

.stride) case .Float16: - float32ToFloat16(input: data.pointer as! UnsafeMutablePointer, output: buffer.contents(), count: count) + try float32ToFloat16(input: data.pointer as! UnsafeMutablePointer, output: buffer.contents(), count: count) } } } else if C == 1 && !padWhenOneC { @@ -351,12 +356,16 @@ class Tensor: Tensorial { case .Float32: buffer?.contents().copyMemory(from: data.pointer, byteCount: numel() * MemoryLayout

.stride) case .Float16: - float32ToFloat16(input: data.pointer as! UnsafeMutablePointer, output: buffer.contents(), count: numel()) + try float32ToFloat16(input: data.pointer as! UnsafeMutablePointer, output: buffer.contents(), count: numel()) } } } else { buffer = device.makeBuffer(length: count * precisionSize) let convertedPointer = UnsafeMutablePointer

.allocate(capacity: count) + defer { + convertedPointer.deinitialize(count: count) + convertedPointer.deallocate() + } var tmpPointer = data.pointer var dstPtr = convertedPointer for _ in 0..: Tensorial { case .Float32: buffer?.contents().copyMemory(from: convertedPointer, byteCount: count * MemoryLayout

.stride) case .Float16: - float32ToFloat16(input: convertedPointer as! UnsafeMutablePointer, output: buffer.contents(), count: count) + try float32ToFloat16(input: convertedPointer as! UnsafeMutablePointer, output: buffer.contents(), count: count) } } - convertedPointer.deinitialize(count: count) - convertedPointer.deallocate() } } else { let C = dim[3] @@ -400,14 +407,18 @@ class Tensor: Tensorial { case .Float32: buffer?.contents().copyMemory(from: data.pointer, byteCount: count * MemoryLayout

.stride) case .Float16: - float32ToFloat16(input: data.pointer as! UnsafeMutablePointer, output: buffer.contents(), count: count) + try float32ToFloat16(input: data.pointer as! UnsafeMutablePointer, output: buffer.contents(), count: count) } } } else if C == 1 { - fatalError(" not support ") + throw PaddleMobileError.makeError(type: .netError, msg: "Tensor initBuffer channel can not be 1") } else { buffer = device.makeBuffer(length: count * precisionSize) let convertedPointer = UnsafeMutablePointer

.allocate(capacity: count) + defer { + convertedPointer.deinitialize(count: count) + convertedPointer.deallocate() + } var tmpPointer = data.pointer var dstPtr = convertedPointer for _ in 0..: Tensorial { case .Float32: buffer?.contents().copyMemory(from: convertedPointer, byteCount: count * MemoryLayout

.stride) case .Float16: - float32ToFloat16(input: convertedPointer as! UnsafeMutablePointer, output: buffer.contents(), count: count) + try float32ToFloat16(input: convertedPointer as! UnsafeMutablePointer, output: buffer.contents(), count: count) } } - convertedPointer.deinitialize(count: count) - convertedPointer.deallocate() } } } else if dim.cout() == 1 { @@ -449,17 +458,17 @@ class Tensor: Tensorial { case .Float32: buffer?.contents().copyMemory(from: data.pointer, byteCount: num * MemoryLayout

.stride) case .Float16: - float32ToFloat16(input: data.pointer as! UnsafeMutablePointer, output: buffer.contents(), count: num) + try float32ToFloat16(input: data.pointer as! UnsafeMutablePointer, output: buffer.contents(), count: num) } } } else { - fatalError(" not support !") + throw PaddleMobileError.makeError(type: .netError, msg: "not support tensor initBuffer dim count \(dim.cout())") } - //TODO: release data.release() } - var n: Int { + + var n: Int? { get { if dim.cout() == 4 { if layout == DataLayout.NCHW() { @@ -467,15 +476,15 @@ class Tensor: Tensorial { } else if layout == DataLayout.NHWC() { return dim[0] } else { - fatalError(" unsupport ") + return nil } } else { - fatalError() + return nil } } } - - var width: Int { + + var width: Int? { get { if dim.cout() == 4 { if layout == DataLayout.NHWC() { @@ -483,15 +492,15 @@ class Tensor: Tensorial { } else if layout == DataLayout.NCHW() { return dim[3] } else { - fatalError(" unsupport ") + return nil } } else { - fatalError() + return nil } } } - - var height: Int { + + var height: Int? { get { if dim.cout() == 4 { if layout == DataLayout.NHWC() { @@ -499,15 +508,15 @@ class Tensor: Tensorial { } else if layout == DataLayout.NCHW() { return dim[2] } else { - fatalError(" unsupport ") + return nil } } else { - fatalError() + return nil } } } - - var channel: Int { + + var channel: Int? { get { if dim.cout() == 4 { if layout == DataLayout.NHWC() { @@ -515,10 +524,10 @@ class Tensor: Tensorial { } else if layout == DataLayout.NCHW() { return dim[1] } else { - fatalError(" unsupport ") + return nil } } else { - fatalError() + return nil } } } @@ -559,14 +568,14 @@ extension Tensor { } func logDataPointer(header: String = "") { - print(header) + paddleMobileLog(header) var str = "" str += "data count: \(data.count) \n" str += "dim: \(dim) \n" for i in 0.. Int { - return metalTexture.width * metalTexture.height * metalTexture.arrayLength * 4 + if let tmpMetalTexture = _metalTexture { + return tmpMetalTexture.width * tmpMetalTexture.height * tmpMetalTexture.arrayLength * 4 + } else if let tmpTextureDesc = textureDesc { + return tmpTextureDesc.width * tmpTextureDesc.height * tmpTextureDesc.arrayLength * 4 + } else { + paddleMobileLog("texture desc nil, using tensorDim.numel() as element count may cause trouble", logLevel: .Warning) + return tensorDim.numel() + } } - func toTensor() -> [Float32] { - guard padToFourDim.cout() == 4 else { - fatalError("- not support -") + func toTensor() throws -> [Float32] { + guard padToFourDim.cout() == 4 else { + throw PaddleMobileError.makeError(type: .netError, msg: "Texture toTensor padToFourDim count must be 4") } - return metalTexture.toTensor(dim: (n: dim[0], c: dim[3], h: dim[1], w: dim[2])) + guard let tmpMetalTexture = metalTexture else { + throw PaddleMobileError.makeError(type: .netError, msg: "metaltexture nil") + } + return try tmpMetalTexture.toTensor(dim: (n: dim[0], c: dim[3], h: dim[1], w: dim[2])) } - func realNHWC() -> [Float32] { + func realNHWC() throws -> [Float32] { guard padToFourDim.cout() == 4 else { - fatalError(" - not support - ") + throw PaddleMobileError.makeError(type: .netError, msg: "Texture toTensor padToFourDim count must be 4") + } + guard let tmpMetalTexture = metalTexture else { + throw PaddleMobileError.makeError(type: .netError, msg: "metaltexture nil") } - return metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3])) + return try tmpMetalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3])) } - + public func initTexture(device: MTLDevice, inTranspose: [Int] = [0, 1, 2, 3], computePrecision: Precision = .Float16) throws { transpose = inTranspose for i in 0..<(4 - tensorDim.cout()) { if i != inTranspose[i] { -// fatalError() - throw PaddleMobileError.loaderError(message: " dims error ") + throw PaddleMobileError.makeError(type: .loaderError, msg: "dims error") } } - let newDim = transpose.map { padToFourDim[$0] } let newLayout = transpose.map { layout.layoutWithDim[$0] } @@ -132,8 +156,7 @@ public class Texture: Tensorial { tmpTextureDes.height = newDim[2] tmpTextureDes.arrayLength = 1 default: -// fatalError("unreachable") - throw PaddleMobileError.loaderError(message: " unreachable ") + throw PaddleMobileError.makeError(type: .loaderError, msg: "unreachable") } if computePrecision == .Float16 { @@ -161,10 +184,7 @@ public class Texture: Tensorial { tmpTextureDes.usage = [.shaderRead, .shaderWrite] tmpTextureDes.storageMode = .shared textureDesc = tmpTextureDes - guard let inTexture = device.makeTexture(descriptor: tmpTextureDes) else { - throw PaddleMobileError.loaderError(message: " create texture is nil ") - } - metalTexture = inTexture + _metalTexture = nil } public func updateDims(inTensorDim: Dim, inDim: Dim) throws { @@ -179,8 +199,7 @@ public class Texture: Tensorial { fourDimNum.append(contentsOf: inDim.dims) fourDim = Dim.init(inDim: fourDimNum) } else { -// fatalError(" not support ") - throw PaddleMobileError.loaderError(message: " not support ") + throw PaddleMobileError.makeError(type: .loaderError, msg: "not support") } tensorDim = inTensorDim @@ -189,10 +208,11 @@ public class Texture: Tensorial { } // 初始化时 dim padToFourDim 模型中的维度(一般来说 nchw),前面补全0 - init(device: MTLDevice, inDim: Dim) { + init(device: MTLDevice, inDim: Dim) throws { if GlobalConfig.shared.debug { print(" in dim > \(inDim)") } + self.device = device var fourDim: Dim if inDim.cout() == 4 { fourDim = inDim @@ -204,7 +224,7 @@ public class Texture: Tensorial { fourDimNum.append(contentsOf: inDim.dims) fourDim = Dim.init(inDim: fourDimNum) } else { - fatalError(" not support ") + throw PaddleMobileError.makeError(type: .netError, msg: "Texture init: dim count \(inDim) unsupported") } tensorDim = inDim dim = fourDim @@ -223,9 +243,20 @@ extension Texture { public var debugDescription: String{ var str = "" str += "Dim: \(dim) \n value:[ " - str += "\(metalTexture.description)" + str += "\(_metalTexture?.description ?? "")" str += " ]" return str } + public func delog() { + if self.transpose == [0, 2, 3, 1] { + let outputArray = (try? self.metalTexture?.toTensor(dim: (n: self.padToFourDim[0], c: self.padToFourDim[1], h: self.padToFourDim[2], w: self.padToFourDim[3]))) ?? [] + print(outputArray?.strideArray() ?? []) + } else if self.transpose == [0, 1, 2, 3] { + let outputArray = (try? self.realNHWC()) ?? [] + print(outputArray.strideArray()) + } else { + paddleMobileLog("unsupported transpose: \(self.transpose)", logLevel: .Warning) + } + } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Framework/Utils.swift b/metal/paddle-mobile/paddle-mobile/Src/Framework/Utils.swift new file mode 100644 index 0000000000..62588a9b53 --- /dev/null +++ b/metal/paddle-mobile/paddle-mobile/Src/Framework/Utils.swift @@ -0,0 +1,29 @@ +/* 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 + +enum PaddleMobileLogLevel: String { + case Info = "Info" + case Warning = "Warning" + case FatalError = "FatalError" +} + +func paddleMobileLog(_ msg: String, logLevel: PaddleMobileLogLevel = .Info, file: String = #file, line: Int = #line, function: String = #function, callStack: Array? = nil) { + var msg = "PaddleMobileLog-\(logLevel.rawValue): \(msg) -file: \(file) -line: \(line) -function:\(function)" + if let callStack = callStack { + msg.append(contentsOf: " -calling stack: \(callStack)") + } + print(msg) +} diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/OpCreator.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/OpCreator.swift index 4fc1974c66..4aa8fac608 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/OpCreator.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/OpCreator.swift @@ -29,14 +29,10 @@ class OpCreator { func creat(device: MTLDevice, opDesc: PMOpDesc, scope: Scope, initContext: InitContext) throws -> Runable & InferShaperable { guard let opCreator = opCreators[opDesc.type] else { - throw PaddleMobileError.opError(message: "there is no " + opDesc.type + " yet") + throw PaddleMobileError.makeError(type: .opError, msg: "there is no " + opDesc.type + " yet") } - do { - return try opCreator(device, opDesc, scope, initContext) - } catch let error { - throw error - } + return try opCreator(device, opDesc, scope, initContext) } let opCreators: [String : (MTLDevice, PMOpDesc, Scope, InitContext) throws -> Runable & InferShaperable] = diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/OpParam.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/OpParam.swift index 37a847b750..b3009cac30 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/OpParam.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/OpParam.swift @@ -61,159 +61,98 @@ extension OpParam { static func getFirstTensor(key: String, map: [String : [String]], from: Scope) throws -> VarType { guard let mapKeys = map[key], mapKeys.count > 0 else { - throw PaddleMobileError.paramError(message: key + " not found in \(map) or maped values is empty") + throw PaddleMobileError.makeError(type: .paramError, msg: key + " not found in \(map) or maped values is empty") } guard let variant = from[mapKeys[0]] else { - throw PaddleMobileError.paramError(message: mapKeys[0] + " not found in scope") + throw PaddleMobileError.makeError(type: .paramError, msg: mapKeys[0] + " not found in scope") } guard let v = variant as? VarType else { - throw PaddleMobileError.paramError(message: " type error") - + throw PaddleMobileError.makeError(type: .paramError, msg: "type error") } return v } static func outputVariances(outputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorVariances: VarType = try getFirstTensor(key: "Variances", map: outputs, from: from) - return tensorVariances - } catch let error { - throw error - } + let tensorVariances: VarType = try getFirstTensor(key: "Variances", map: outputs, from: from) + return tensorVariances } static func paramInputAlpha(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let alphaTensor: VarType = try getFirstTensor(key: "Alpha", map: inputs, from: from) - return alphaTensor - } catch let error { - throw error - } + let alphaTensor: VarType = try getFirstTensor(key: "Alpha", map: inputs, from: from) + return alphaTensor } static func inputImage(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorImage: VarType = try getFirstTensor(key: "Image", map: inputs, from: from) - return tensorImage - } catch let error { - throw error - } + let tensorImage: VarType = try getFirstTensor(key: "Image", map: inputs, from: from) + return tensorImage } static func inputX(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorX: VarType = try getFirstTensor(key: "X", map: inputs, from: from) - return tensorX - } catch let error { - throw error - } + let tensorX: VarType = try getFirstTensor(key: "X", map: inputs, from: from) + return tensorX } static func outputBoxes(outputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorBox: VarType = try getFirstTensor(key: "Boxes", map: outputs, from: from) - return tensorBox - } catch let error { - throw error - } + let tensorBox: VarType = try getFirstTensor(key: "Boxes", map: outputs, from: from) + return tensorBox } static func input(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorInput: VarType = try getFirstTensor(key: "Input", map: inputs, from: from) - return tensorInput - } catch let error { - throw error - } + let tensorInput: VarType = try getFirstTensor(key: "Input", map: inputs, from: from) + return tensorInput } static func output(outputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorOutput: VarType = try getFirstTensor(key: "Output", map: outputs, from: from) - return tensorOutput - } catch let error { - throw error - } + let tensorOutput: VarType = try getFirstTensor(key: "Output", map: outputs, from: from) + return tensorOutput } static func outputY(outputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorOutputY: VarType = try getFirstTensor(key: "Y", map: outputs, from: from) - return tensorOutputY - } catch let error { - throw error - } + let tensorOutputY: VarType = try getFirstTensor(key: "Y", map: outputs, from: from) + return tensorOutputY } static func inputY(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorY: VarType = try getFirstTensor(key: "Y", map: inputs, from: from) - return tensorY - } catch let error { - throw error - } + let tensorY: VarType = try getFirstTensor(key: "Y", map: inputs, from: from) + return tensorY } static func outputOut(outputs: [String : [String]], from: Scope) throws -> VarType { - do { - let out: VarType = try getFirstTensor(key: "Out", map: outputs, from: from) - return out - } catch let error { - throw error - } + let out: VarType = try getFirstTensor(key: "Out", map: outputs, from: from) + return out } static func inputFilter(paraInputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorFilter: VarType = try getFirstTensor(key: "Filter", map: paraInputs, from: from) - return tensorFilter - } catch let error { - throw error - } + let tensorFilter: VarType = try getFirstTensor(key: "Filter", map: paraInputs, from: from) + return tensorFilter } static func inputBiase(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorBias: VarType = try getFirstTensor(key: "Bias", map: inputs, from: from) - return tensorBias - } catch let error { - throw error - } + let tensorBias: VarType = try getFirstTensor(key: "Bias", map: inputs, from: from) + return tensorBias } static func inputMean(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorMean: VarType = try getFirstTensor(key: "Mean", map: inputs, from: from) - return tensorMean - } catch let error { - throw error - } + let tensorMean: VarType = try getFirstTensor(key: "Mean", map: inputs, from: from) + return tensorMean } static func inputScale(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorScale: VarType = try getFirstTensor(key: "Scale", map: inputs, from: from) - return tensorScale - } catch let error { - throw error - } + let tensorScale: VarType = try getFirstTensor(key: "Scale", map: inputs, from: from) + return tensorScale } static func inputVariance(inputs: [String : [String]], from: Scope) throws -> VarType { - do { - let tensorVariance: VarType = try getFirstTensor(key: "Variance", map: inputs, from: from) - return tensorVariance - } catch let error { - throw error - } + let tensorVariance: VarType = try getFirstTensor(key: "Variance", map: inputs, from: from) + return tensorVariance } - static func getAttr(key: String, attrs: [String : Attr]) throws -> T{ + static func getAttr(key: String, attrs: [String : Attr]) throws -> T { guard let attr = attrs[key] else { - throw PaddleMobileError.paramError(message: "attr \(key) can't found in: \(attrs)" ) + throw PaddleMobileError.makeError(type: .paramError, msg: "attr \(key) can't found in: \(attrs)") } guard let tAttr = attr as? T else { - throw PaddleMobileError.paramError(message: "key: \(key) attr: \(attr) type error" ) + throw PaddleMobileError.makeError(type: .paramError, msg: "key: \(key) attr: \(attr) type error") } return tAttr } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/Operator.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/Operator.swift index a89dfa3b86..1a033df092 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/Operator.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Base/Operator.swift @@ -31,30 +31,25 @@ protocol Runable { func run(device: MTLDevice, buffer: MTLCommandBuffer) throws func runImpl(device: MTLDevice,buffer: MTLCommandBuffer) throws func delogOutput() - func inputVariant() -> [String : [MTLBuffer]] - func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) + func inputVariant() -> [String : [MTLBuffer]]? + func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) throws } -extension Runable where Self: OperatorProtocol{ +extension Runable where Self: OperatorProtocol { func run(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try runImpl(device: device, buffer: buffer) - } catch let error { - throw error - } + try runImpl(device: device, buffer: buffer) } - func inputVariant() -> [String : [MTLBuffer]] { + func inputVariant() -> [String : [MTLBuffer]]? { // return [:] - fatalError(" op \(type) need implement inputVariant") + return nil } - func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) { - fatalError(" need implement ") + func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) throws { + throw PaddleMobileError.makeError(type: .netError, msg: "need implement func computeMiddleResult") } func delogOutput() { - print(type + ": has no implementation" ) } } @@ -86,11 +81,7 @@ protocol Creator where Self: OperatorProtocol{ extension Creator where Self: OperatorProtocol { static func creat(device: MTLDevice, opDesc: PMOpDesc, inScope: Scope, initContext: InitContext) throws -> OpType { - do { - return try OpType.provide(device:device, opDesc: opDesc, inScope: inScope, initContext: initContext) - } catch let error { - throw error - } + return try OpType.provide(device:device, opDesc: opDesc, inScope: inScope, initContext: initContext) } } @@ -114,11 +105,7 @@ protocol OperatorProtocol { extension OperatorProtocol { static func provide(device: MTLDevice, opDesc: PMOpDesc, inScope: Scope, initContext: InitContext) throws -> Self { - do { - return try Self.init(device: device, opDesc: opDesc, inScope: inScope, initContext: initContext) - } catch let error { - throw error - } + return try Self.init(device: device, opDesc: opDesc, inScope: inScope, initContext: initContext) } } @@ -130,12 +117,8 @@ class Operator : OperatorProtocol where outpus = opDesc.outputs attrs = opDesc.attrs paraInputs = opDesc.paraInputs - do { - para = try ParamType.init(opDesc:opDesc, inScope: inScope) - kernel = try KernelType.init(device: device, param: para, initContext: initContext) - } catch let error { - throw error - } + para = try ParamType.init(opDesc:opDesc, inScope: inScope) + kernel = try KernelType.init(device: device, param: para, initContext: initContext) } typealias ParamType = ParameterType diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/BatchNormOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/BatchNormOp.swift index 7e53ea8d1c..7cbb22b58d 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/BatchNormOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/BatchNormOp.swift @@ -18,21 +18,17 @@ import Metal class BatchNormParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try BatchNormParam.inputX(inputs: opDesc.inputs, from: inScope) - if input.transpose != [0, 2, 3, 1] { - fatalError("batch norm only accepts NHWC") - } - output = try BatchNormParam.outputY(outputs: opDesc.outputs, from: inScope) - bias = try BatchNormParam.getFirstTensor(key: "Bias", map: opDesc.paraInputs, from: inScope) - mean = try BatchNormParam.getFirstTensor(key: "Mean", map: opDesc.paraInputs, from: inScope) - scale = try BatchNormParam.getFirstTensor(key: "Scale", map: opDesc.paraInputs, from: inScope) - variance = try BatchNormParam.getFirstTensor(key: "Variance", map: opDesc.paraInputs, from: inScope) - epsilon = try BatchNormParam.getAttr(key: "epsilon", attrs: opDesc.attrs) - momentum = try BatchNormParam.getAttr(key: "momentum", attrs: opDesc.attrs) - } catch let error { - throw error + input = try BatchNormParam.inputX(inputs: opDesc.inputs, from: inScope) + if input.transpose != [0, 2, 3, 1] { + throw PaddleMobileError.makeError(type: .netError, msg: "batch norm only accepts NHWC") } + output = try BatchNormParam.outputY(outputs: opDesc.outputs, from: inScope) + bias = try BatchNormParam.getFirstTensor(key: "Bias", map: opDesc.paraInputs, from: inScope) + mean = try BatchNormParam.getFirstTensor(key: "Mean", map: opDesc.paraInputs, from: inScope) + scale = try BatchNormParam.getFirstTensor(key: "Scale", map: opDesc.paraInputs, from: inScope) + variance = try BatchNormParam.getFirstTensor(key: "Variance", map: opDesc.paraInputs, from: inScope) + epsilon = try BatchNormParam.getAttr(key: "epsilon", attrs: opDesc.attrs) + momentum = try BatchNormParam.getAttr(key: "momentum", attrs: opDesc.attrs) } let input: Texture var output: Texture @@ -51,17 +47,11 @@ class BatchNormOp: Operator, BatchNormP para.output.dim = para.input.dim } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - let device = para.output.metalTexture!.device - let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose) - print(outputArray.strideArray()) + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/BilinearInterpOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/BilinearInterpOp.swift index 51703c3e6f..a2cb5be3bc 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/BilinearInterpOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/BilinearInterpOp.swift @@ -18,16 +18,12 @@ import Metal class BilinearInterpParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try BilinearInterpParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try BilinearInterpParam.outputOut(outputs: opDesc.outputs, from: inScope) - out_h = try BilinearInterpParam.getAttr(key: "out_h", attrs: opDesc.attrs) - out_w = try BilinearInterpParam.getAttr(key: "out_w", attrs: opDesc.attrs) - } catch let error { - throw error - } + input = try BilinearInterpParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try BilinearInterpParam.outputOut(outputs: opDesc.outputs, from: inScope) + out_h = try BilinearInterpParam.getAttr(key: "out_h", attrs: opDesc.attrs) + out_w = try BilinearInterpParam.getAttr(key: "out_w", attrs: opDesc.attrs) if (input.transpose != [0, 2, 3, 1]) || (input.tensorDim.cout() != 4) { - fatalError() + throw PaddleMobileError.makeError(type: .netError, msg: "BilinearInterpParam input transpose or tensordim not supported") } } let input: Texture @@ -45,19 +41,12 @@ class BilinearInterpOp: Operator, } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - let device = para.output.metalTexture!.device - let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose) - // print(outputArray) - print(outputArray.strideArray()) + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/BoxcoderOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/BoxcoderOp.swift index 0ca6325922..f829cd3332 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/BoxcoderOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/BoxcoderOp.swift @@ -17,25 +17,26 @@ import Foundation class BoxcoderParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, 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 + 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) + + guard priorBox.tensorDim.cout() == 2 && + priorBoxVar.tensorDim.cout() == 2 && + targetBox.tensorDim.cout() == 3 && + output.tensorDim.cout() == 3 && + priorBox.transpose == [0, 1, 2, 3] && + priorBoxVar.transpose == [0, 1, 2, 3] && + targetBox.transpose == [0, 1, 2, 3] && + codeType == "decode_center_size" && + targetBox.tensorDim.cout() == 3 && + targetBox.tensorDim[0] == 1 + else { + throw PaddleMobileError.makeError(type: .netError, msg:"param do not satisfiy") } - assert(priorBox.tensorDim.cout() == 2) - assert(priorBoxVar.tensorDim.cout() == 2) - assert(targetBox.tensorDim.cout() == 3) - assert(output.tensorDim.cout() == 3) - 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 @@ -54,28 +55,19 @@ class BoxcoderOp: Operator, BoxcoderPara } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - let device = para.output.metalTexture!.device - let pbv : [Float32] = device.texture2tensor(texture: para.priorBoxVar.metalTexture!, dim: para.priorBoxVar.tensorDim.dims, transpose: para.priorBoxVar.transpose) - let pb : [Float32] = device.texture2tensor(texture: para.priorBox.metalTexture!, dim: para.priorBox.tensorDim.dims, transpose: para.priorBox.transpose) - let tb : [Float32] = device.texture2tensor(texture: para.targetBox.metalTexture!, dim: para.targetBox.tensorDim.dims, transpose: para.targetBox.transpose) - let out : [Float32] = device.texture2tensor(texture: para.output.metalTexture!, dim: para.output.tensorDim.dims, transpose: para.output.transpose) print(" prior box var ") - print(pbv.strideArray()) + para.priorBoxVar.delog() print(" target box ") - print(tb.strideArray()) + para.targetBox.delog() print(" prior box ") - print(pb.strideArray()) + para.priorBox.delog() print(" output ") - print(out.strideArray()) + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConcatOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConcatOp.swift index 6cf8d741a9..5813a3c2eb 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConcatOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConcatOp.swift @@ -17,37 +17,33 @@ import Foundation class ConcatParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - guard let xlist = opDesc.inputs["X"] else { - fatalError() + guard let xlist = opDesc.inputs["X"] else { + throw PaddleMobileError.makeError(type: .netError, msg: "concat input desc nil") + } + for x in xlist { + guard let variant = inScope[x], let v = variant as? Texture else { + throw PaddleMobileError.makeError(type: .netError, msg: "concat input texture nil") } - for x in xlist { - guard let variant = inScope[x], let v = variant as? Texture else { - fatalError() - } - if transpose.count == 0 { - transpose = v.transpose - } - if v.transpose != transpose { - fatalError() - } - - input.append(v) + if transpose.count == 0 { + transpose = v.transpose } - axis = try ConcatParam.getAttr(key: "axis", attrs: opDesc.attrs) - if input.count > 0 { - if let originDimsCount = input[0].originDimsCount { - let nowDimsCount = input[0].dim.cout() - let diff = originDimsCount - nowDimsCount - if diff > 0 { - axis -= diff - } + if v.transpose != transpose { + throw PaddleMobileError.makeError(type: .netError, msg: "concat transpose not equal") + } + + input.append(v) + } + axis = try ConcatParam.getAttr(key: "axis", attrs: opDesc.attrs) + if input.count > 0 { + if let originDimsCount = input[0].originDimsCount { + let nowDimsCount = input[0].dim.cout() + let diff = originDimsCount - nowDimsCount + if diff > 0 { + axis -= diff } } - output = try ConcatParam.outputOut(outputs: opDesc.outputs, from: inScope) - } catch let error { - throw error } + output = try ConcatParam.outputOut(outputs: opDesc.outputs, from: inScope) } var input: [Texture] = [] var output: Texture @@ -65,19 +61,12 @@ class ConcatOp: Operator, ConcatParam

>, } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - - let device = para.output.metalTexture!.device - let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose) - print(outputArray.strideArray()) + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddAddPreluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddAddPreluOp.swift index f22a0026d3..ff97b4122a 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddAddPreluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddAddPreluOp.swift @@ -18,20 +18,16 @@ import Metal class ConvAddAddPreluParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - filter = try ConvAddAddPreluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) - input = try ConvAddAddPreluParam.input(inputs: opDesc.inputs, from: inScope) - output = try ConvAddAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope) - stride = try ConvAddAddPreluParam.getAttr(key: "strides", attrs: opDesc.attrs) - paddings = try ConvAddAddPreluParam.getAttr(key: "paddings", attrs: opDesc.attrs) - dilations = try ConvAddAddPreluParam.getAttr(key: "dilations", attrs: opDesc.attrs) - groups = try ConvAddAddPreluParam.getAttr(key: "groups", attrs: opDesc.attrs) - alpha = try ConvAddAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) - mode = try ConvAddAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs) - y = try ConvAddAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope) - } catch let error { - throw error - } + filter = try ConvAddAddPreluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) + input = try ConvAddAddPreluParam.input(inputs: opDesc.inputs, from: inScope) + output = try ConvAddAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope) + stride = try ConvAddAddPreluParam.getAttr(key: "strides", attrs: opDesc.attrs) + paddings = try ConvAddAddPreluParam.getAttr(key: "paddings", attrs: opDesc.attrs) + dilations = try ConvAddAddPreluParam.getAttr(key: "dilations", attrs: opDesc.attrs) + groups = try ConvAddAddPreluParam.getAttr(key: "groups", attrs: opDesc.attrs) + alpha = try ConvAddAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) + mode = try ConvAddAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs) + y = try ConvAddAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope) } let input: Texture @@ -93,17 +89,17 @@ class ConvAddAddPreluOp: Operator } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - 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()) + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddBatchNormReluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddBatchNormReluOp.swift index dd08da27ac..3ad1f332cc 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddBatchNormReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddBatchNormReluOp.swift @@ -18,26 +18,21 @@ import Foundation class ConvAddBatchNormReluParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - - filter = try ConvAddBatchNormReluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) - input = try ConvAddBatchNormReluParam.input(inputs: opDesc.inputs, from: inScope) - output = try ConvAddBatchNormReluParam.outputOut(outputs: opDesc.outputs, from: inScope) - stride = try ConvAddBatchNormReluParam.getAttr(key: "strides", attrs: opDesc.attrs) - paddings = try ConvAddBatchNormReluParam.getAttr(key: "paddings", attrs: opDesc.attrs) - dilations = try ConvAddBatchNormReluParam.getAttr(key: "dilations", attrs: opDesc.attrs) - epsilon = try ConvAddBatchNormReluParam.getAttr(key: "epsilon", attrs: opDesc.attrs) - - groups = try ConvAddBatchNormReluParam.getAttr(key: "groups", attrs: opDesc.attrs) - variance = try ConvAddBatchNormReluParam.inputVariance(inputs: opDesc.paraInputs, from: inScope) - bias = try ConvAddBatchNormReluParam.inputBiase(inputs: opDesc.paraInputs, from: inScope) - - scale = try ConvAddBatchNormReluParam.inputScale(inputs: opDesc.paraInputs, from: inScope) - mean = try ConvAddBatchNormReluParam.inputMean(inputs: opDesc.paraInputs, from: inScope) - y = try ConvAddBatchNormReluParam.inputY(inputs: opDesc.paraInputs, from: inScope) - } catch let error { - throw error - } + filter = try ConvAddBatchNormReluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) + input = try ConvAddBatchNormReluParam.input(inputs: opDesc.inputs, from: inScope) + output = try ConvAddBatchNormReluParam.outputOut(outputs: opDesc.outputs, from: inScope) + stride = try ConvAddBatchNormReluParam.getAttr(key: "strides", attrs: opDesc.attrs) + paddings = try ConvAddBatchNormReluParam.getAttr(key: "paddings", attrs: opDesc.attrs) + dilations = try ConvAddBatchNormReluParam.getAttr(key: "dilations", attrs: opDesc.attrs) + epsilon = try ConvAddBatchNormReluParam.getAttr(key: "epsilon", attrs: opDesc.attrs) + + groups = try ConvAddBatchNormReluParam.getAttr(key: "groups", attrs: opDesc.attrs) + variance = try ConvAddBatchNormReluParam.inputVariance(inputs: opDesc.paraInputs, from: inScope) + bias = try ConvAddBatchNormReluParam.inputBiase(inputs: opDesc.paraInputs, from: inScope) + + scale = try ConvAddBatchNormReluParam.inputScale(inputs: opDesc.paraInputs, from: inScope) + mean = try ConvAddBatchNormReluParam.inputMean(inputs: opDesc.paraInputs, from: inScope) + y = try ConvAddBatchNormReluParam.inputY(inputs: opDesc.paraInputs, from: inScope) } let input: Texture @@ -86,11 +81,7 @@ class ConvAddBatchNormReluOp: Operator Node { @@ -112,7 +103,11 @@ class ConvAddBatchNormReluOp: Operator: Operator, ConvAddReluPar } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - 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()) + print(para.output.metalTexture ?? "") + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddPreluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddPreluOp.swift index 03cbeb8187..30e332d739 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddPreluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddPreluOp.swift @@ -17,20 +17,16 @@ import Foundation class ConvAddPreluParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - filter = try ConvAddPreluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) - input = try ConvAddPreluParam.input(inputs: opDesc.inputs, from: inScope) - output = try ConvAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope) - stride = try ConvAddPreluParam.getAttr(key: "strides", attrs: opDesc.attrs) - paddings = try ConvAddPreluParam.getAttr(key: "paddings", attrs: opDesc.attrs) - dilations = try ConvAddPreluParam.getAttr(key: "dilations", attrs: opDesc.attrs) - groups = try ConvAddPreluParam.getAttr(key: "groups", attrs: opDesc.attrs) - alpha = try ConvAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) - mode = try ConvAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs) - y = try ConvAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope) - } catch let error { - throw error - } + filter = try ConvAddPreluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) + input = try ConvAddPreluParam.input(inputs: opDesc.inputs, from: inScope) + output = try ConvAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope) + stride = try ConvAddPreluParam.getAttr(key: "strides", attrs: opDesc.attrs) + paddings = try ConvAddPreluParam.getAttr(key: "paddings", attrs: opDesc.attrs) + dilations = try ConvAddPreluParam.getAttr(key: "dilations", attrs: opDesc.attrs) + groups = try ConvAddPreluParam.getAttr(key: "groups", attrs: opDesc.attrs) + alpha = try ConvAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) + mode = try ConvAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs) + y = try ConvAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope) } let input: Texture @@ -86,16 +82,16 @@ class ConvAddPreluOp: Operator, Conv } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - 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()) + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddReluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddReluOp.swift index 72be568a67..1acdee3dd6 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvAddReluOp.swift @@ -35,9 +35,9 @@ class ConvAddReluParam: OpParam { do { let yTensor: Tensor

= try ConvAddReluParam.inputY(inputs: opDesc.paraInputs, from: inScope) let device = input.metalTexture!.device - y = Texture.init(device: device, inDim: yTensor.dim) + y = try Texture.init(device: device, inDim: yTensor.dim) let value: [P] = Array(UnsafeBufferPointer(start: yTensor.data.pointer, count: yTensor.dim.numel())) - y?.metalTexture = device.tensor2texture(value: value, dim: yTensor.dim.dims, transpose: [0, 1, 2, 3], inComputePrecision: GlobalConfig.shared.computePrecision) + y?.metalTexture = try device.tensor2texture(value: value, dim: yTensor.dim.dims, transpose: [0, 1, 2, 3], inComputePrecision: GlobalConfig.shared.computePrecision) self.yTensor = yTensor } catch { } @@ -106,16 +106,16 @@ class ConvAddReluOp: Operator, ConvAd } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - 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()) + print(para.output.metalTexture ?? "") + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvBNReluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvBNReluOp.swift index adbad35b47..9493636edd 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvBNReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvBNReluOp.swift @@ -17,23 +17,19 @@ import Foundation class ConvBNReluParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - filter = try ConvBNReluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) - input = try ConvBNReluParam.input(inputs: opDesc.inputs, from: inScope) - output = try ConvBNReluParam.outputOut(outputs: opDesc.outputs, from: inScope) - stride = try ConvBNReluParam.getAttr(key: "strides", attrs: opDesc.attrs) - paddings = try ConvBNReluParam.getAttr(key: "paddings", attrs: opDesc.attrs) - dilations = try ConvBNReluParam.getAttr(key: "dilations", attrs: opDesc.attrs) - epsilon = try ConvBNReluParam.getAttr(key: "epsilon", attrs: opDesc.attrs) - - groups = try ConvBNReluParam.getAttr(key: "groups", attrs: opDesc.attrs) - variance = try ConvBNReluParam.inputVariance(inputs: opDesc.paraInputs, from: inScope) - bias = try ConvBNReluParam.inputBiase(inputs: opDesc.paraInputs, from: inScope) - scale = try ConvBNReluParam.inputScale(inputs: opDesc.paraInputs, from: inScope) - mean = try ConvBNReluParam.inputMean(inputs: opDesc.paraInputs, from: inScope) - } catch let error { - throw error - } + filter = try ConvBNReluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) + input = try ConvBNReluParam.input(inputs: opDesc.inputs, from: inScope) + output = try ConvBNReluParam.outputOut(outputs: opDesc.outputs, from: inScope) + stride = try ConvBNReluParam.getAttr(key: "strides", attrs: opDesc.attrs) + paddings = try ConvBNReluParam.getAttr(key: "paddings", attrs: opDesc.attrs) + dilations = try ConvBNReluParam.getAttr(key: "dilations", attrs: opDesc.attrs) + epsilon = try ConvBNReluParam.getAttr(key: "epsilon", attrs: opDesc.attrs) + + groups = try ConvBNReluParam.getAttr(key: "groups", attrs: opDesc.attrs) + variance = try ConvBNReluParam.inputVariance(inputs: opDesc.paraInputs, from: inScope) + bias = try ConvBNReluParam.inputBiase(inputs: opDesc.paraInputs, from: inScope) + scale = try ConvBNReluParam.inputScale(inputs: opDesc.paraInputs, from: inScope) + mean = try ConvBNReluParam.inputMean(inputs: opDesc.paraInputs, from: inScope) } let input: Texture @@ -84,11 +80,7 @@ class ConvBNReluOp: Operator, ConvBNRe } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } static func fusionNode() -> Node { @@ -109,7 +101,11 @@ class ConvBNReluOp: Operator, ConvBNRe func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray()) + do { + let output = try para.output.metalTexture?.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvOp.swift index ba1084afab..25221538e9 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvOp.swift @@ -16,18 +16,13 @@ import Foundation class ConvParam: OpParam { required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - filter = try ConvParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) - input = try ConvParam.input(inputs: opDesc.inputs, from: inScope) - output = try ConvParam.output(outputs: opDesc.outputs, from: inScope) - stride = try ConvParam.getAttr(key: "strides", attrs: opDesc.attrs) - paddings = try ConvParam.getAttr(key: "paddings", attrs: opDesc.attrs) - dilations = try ConvParam.getAttr(key: "dilations", attrs: opDesc.attrs) - groups = try ConvParam.getAttr(key: "groups", attrs: opDesc.attrs) - - } catch let error { - throw error - } + filter = try ConvParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) + input = try ConvParam.input(inputs: opDesc.inputs, from: inScope) + output = try ConvParam.output(outputs: opDesc.outputs, from: inScope) + stride = try ConvParam.getAttr(key: "strides", attrs: opDesc.attrs) + paddings = try ConvParam.getAttr(key: "paddings", attrs: opDesc.attrs) + dilations = try ConvParam.getAttr(key: "dilations", attrs: opDesc.attrs) + groups = try ConvParam.getAttr(key: "groups", attrs: opDesc.attrs) } let input: Texture @@ -65,16 +60,16 @@ class ConvOp: Operator, ConvParam

>, Runab } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print("conv output : ") - print(para.output.toTensor().strideArray()) + do { + let output = try para.output.toTensor().strideArray() + print(output) + } catch _ { + } // let _: Float16? = para.output.metalTexture.logDesc() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvReluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvReluOp.swift index 4696441292..6ec4ba1f22 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvReluOp.swift @@ -64,7 +64,10 @@ class ConvReluOp: Operator, ConvAddReluP func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - 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()) + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvTransposeOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvTransposeOp.swift index 57269354a1..2d19772f37 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvTransposeOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ConvTransposeOp.swift @@ -17,11 +17,7 @@ import Foundation class ConvTransposeParam: ConvParam

{ //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - try super.init(opDesc: opDesc, inScope: inScope) - } catch let error { - throw error - } + try super.init(opDesc: opDesc, inScope: inScope) } } @@ -34,25 +30,24 @@ class ConvTransposeOp: Operator, Co } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") let padToFourDim = para.output.padToFourDim - if para.output.transpose == [0, 1, 2, 3] { - let outputArray: [Float32] = para.output.metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3])) - print(outputArray.strideArray()) - } else if para.output.transpose == [0, 2, 3, 1] { - let output = 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])) - print(output.strideArray()) - } else { - print(" not implement") + do { + if para.output.transpose == [0, 1, 2, 3] { + let outputArray: [Float32] = try para.output.metalTexture?.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3])) ?? [] + print(outputArray.strideArray()) + } else if para.output.transpose == [0, 2, 3, 1] { + let output = try 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])) ?? [] + print(output.strideArray()) + } else { + print(" not implement") + } + } catch _ { } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/DepthwiseConvOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/DepthwiseConvOp.swift index 49e146b688..b294670822 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/DepthwiseConvOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/DepthwiseConvOp.swift @@ -41,15 +41,15 @@ class DepthConvOp: Operator, ConvParam

>, } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray()) + do { + let output = try para.output.metalTexture?.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/DwConvBNReluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/DwConvBNReluOp.swift index dd3f50c5d4..b7ce696c95 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/DwConvBNReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/DwConvBNReluOp.swift @@ -40,11 +40,7 @@ class DwConvBNReluOp: Operator, ConvBN } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } static func fusionNode() -> Node { @@ -65,6 +61,10 @@ class DwConvBNReluOp: Operator, ConvBN func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray()) + do { + let output = try para.output.metalTexture?.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ElementwiseAddOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ElementwiseAddOp.swift index 73a278e3c7..385ee39ff5 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ElementwiseAddOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ElementwiseAddOp.swift @@ -18,40 +18,29 @@ import Metal class ElementwiseAddParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - inputX = try ElementwiseAddParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try ElementwiseAddParam.outputOut(outputs: opDesc.outputs, from: inScope) - axis = try ElementwiseAddParam.getAttr(key: "axis", attrs: opDesc.attrs) - } catch let error { - throw error - } + inputX = try ElementwiseAddParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try ElementwiseAddParam.outputOut(outputs: opDesc.outputs, from: inScope) + axis = try ElementwiseAddParam.getAttr(key: "axis", attrs: opDesc.attrs) do { inputY = try ElementwiseAddParam.inputY(inputs: opDesc.paraInputs, from: inScope) } catch _ { let tensorY: Tensor

= try ElementwiseAddParam.inputY(inputs: opDesc.paraInputs, from: inScope) - let device = inputX.metalTexture!.device - inputY = Texture.init(device: device, inDim: tensorY.dim) + guard let device = inputX.metalTexture?.device else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "ElementwiseAddParam inputX metalTexture nil") + } + inputY = try Texture.init(device: device, inDim: tensorY.dim) let value: [P] = Array(UnsafeBufferPointer(start: tensorY.data.pointer, count: tensorY.dim.numel())) - inputY.metalTexture = device.tensor2texture(value: value, dim: tensorY.dim.dims, transpose: [0, 1, 2, 3], inComputePrecision: GlobalConfig.shared.computePrecision) + inputY.metalTexture = try device.tensor2texture(value: value, dim: tensorY.dim.dims, transpose: [0, 1, 2, 3], inComputePrecision: GlobalConfig.shared.computePrecision) } - // required init(device: MTLDevice, param: ElementwiseAddParam

) { - // param.output.initTexture(device: device, inTranspose: param.inputX.transpose, computePrecision: computePrecision) - // if computePrecision == .Float32 { - // super.init(device: device, inFunctionName: "elementwise_add") - // } else if computePrecision == .Float16 { - // super.init(device: device, inFunctionName: "elementwise_add_half") - // } else { - // fatalError() - // } - // } - var offset = axis if axis == -1 { offset = inputX.tensorDim.cout() - inputY.tensorDim.cout() } for i in 0..<(inputY.tensorDim.cout()) { - assert(inputX.tensorDim[offset + i] == inputY.tensorDim[i]) + guard inputX.tensorDim[offset + i] == inputY.tensorDim[i] else { + throw PaddleMobileError.makeError(type: .netError, msg:"inputs tensordim inputx: \(inputX.tensorDim) inputy: \(inputY.tensorDim) offset: \(offset) do not satisfy") + } } } @@ -69,11 +58,7 @@ class ElementwiseAddOp: Operator, } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { @@ -81,14 +66,18 @@ class ElementwiseAddOp: Operator, print(para.output) let padToFourDim = para.output.padToFourDim - if para.output.transpose == [0, 1, 2, 3] { - let outputArray: [Float32] = para.output.metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3])) - print(outputArray.strideArray()) - } else if para.output.transpose == [0, 2, 3, 1] { - 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()) - } else { - print(" not implement") + do { + if para.output.transpose == [0, 1, 2, 3] { + let outputArray: [Float32] = try para.output.metalTexture?.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3])) ?? [] + print(outputArray.strideArray()) + } else if para.output.transpose == [0, 2, 3, 1] { + print(try 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() ?? []) + } else { + print(" not implement") + } + } catch _ { } + } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ElementwiseAddPreluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ElementwiseAddPreluOp.swift index bcf0ba994c..7d726a5989 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ElementwiseAddPreluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ElementwiseAddPreluOp.swift @@ -18,42 +18,31 @@ import Metal class ElementwiseAddPreluParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - alpha = try ElementwiseAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) - mode = try ElementwiseAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs) - inputX = try ElementwiseAddPreluParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try ElementwiseAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope) - axis = try ElementwiseAddPreluParam.getAttr(key: "axis", attrs: opDesc.attrs) - } catch let error { - throw error - } + alpha = try ElementwiseAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) + mode = try ElementwiseAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs) + inputX = try ElementwiseAddPreluParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try ElementwiseAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope) + axis = try ElementwiseAddPreluParam.getAttr(key: "axis", attrs: opDesc.attrs) do { inputY = try ElementwiseAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope) } catch _ { let tensorY: Tensor

= try ElementwiseAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope) - let device = inputX.metalTexture!.device - inputY = Texture.init(device: device, inDim: tensorY.dim) + guard let device = inputX.metalTexture?.device else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "ElementwiseAddParam inputX metalTexture nil") + } + inputY = try Texture.init(device: device, inDim: tensorY.dim) let value: [P] = Array(UnsafeBufferPointer(start: tensorY.data.pointer, count: tensorY.dim.numel())) - inputY.metalTexture = device.tensor2texture(value: value, dim: tensorY.dim.dims, transpose: [0, 1, 2, 3], inComputePrecision: GlobalConfig.shared.computePrecision) + inputY.metalTexture = try device.tensor2texture(value: value, dim: tensorY.dim.dims, transpose: [0, 1, 2, 3], inComputePrecision: GlobalConfig.shared.computePrecision) } - // required init(device: MTLDevice, param: ElementwiseAddParam

) { - // param.output.initTexture(device: device, inTranspose: param.inputX.transpose, computePrecision: computePrecision) - // if computePrecision == .Float32 { - // super.init(device: device, inFunctionName: "elementwise_add") - // } else if computePrecision == .Float16 { - // super.init(device: device, inFunctionName: "elementwise_add_half") - // } else { - // fatalError() - // } - // } - var offset = axis if axis == -1 { offset = inputX.tensorDim.cout() - inputY.tensorDim.cout() } for i in 0..<(inputY.tensorDim.cout()) { - assert(inputX.tensorDim[offset + i] == inputY.tensorDim[i]) + guard inputX.tensorDim[offset + i] == inputY.tensorDim[i] else { + throw PaddleMobileError.makeError(type: .netError, msg: "inputs tensordim inputx: \(inputX.tensorDim) inputy: \(inputY.tensorDim) offset: \(offset) do not satisfy") + } } } @@ -88,11 +77,7 @@ class ElementwiseAddPreluOp: Operator: Operator: OpParam { required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try ExpParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try ExpParam.outputOut(outputs: opDesc.outputs, from: inScope) - } catch let error { - throw error - } + input = try ExpParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try ExpParam.outputOut(outputs: opDesc.outputs, from: inScope) } let input: Texture var output: Texture @@ -36,16 +32,16 @@ class ExpOp: Operator, ExpParam

>, Runable, } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - 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()) + print(para.output.metalTexture ?? "") + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/FeedOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/FeedOp.swift index 5022d31205..a15b5079fc 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/FeedOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/FeedOp.swift @@ -25,11 +25,7 @@ class FeedParam: OpParam{ required init(opDesc: PMOpDesc, inScope: Scope) throws { scope = inScope - do { - output = try FeedParam.outputOut(outputs: opDesc.outputs, from: inScope) - } catch let error { - throw error - } + output = try FeedParam.outputOut(outputs: opDesc.outputs, from: inScope) } //typealias ParamPrecisionType = P @@ -40,17 +36,13 @@ class FeedOp: Operator, FeedPa func inferShape() { // print("feed input: \(para.input.expectDim)") - print("feed output: \(para.output.dim)") + paddleMobileLog("feed output: \(para.output.dim)") // para.output.dim = // para.output.dim = para.input.expectDim } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) // let resizeKernel = ResizeKernel

.init(device: device) // let resizeParam = ResizeParam.init(input: para.input.mtlTexture, output: para.output.metalTexture, expectDim: para.input.expectDim) @@ -63,8 +55,13 @@ class FeedOp: Operator, FeedPa func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - print(para.output.toTensor().strideArray()) + print(para.output.metalTexture ?? "") + do { + let output = try para.output.metalTexture?.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray() + print(output ?? "") + } catch let error { + print(error) + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/FetchOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/FetchOp.swift index e9a5a395ae..2f3db88504 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/FetchOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/FetchOp.swift @@ -21,13 +21,9 @@ class FetchParam: OpParam{ let scope: Scope required init(opDesc: PMOpDesc, inScope: Scope) throws { scope = inScope - do { - input = try FetchParam.inputX(inputs: opDesc.inputs, from: inScope) - output = FetchHolder.init(inPaddedCapacity: input.elementCount(), inDim: input.tensorDim) - scope.setOutput(output: output) - } catch let error { - throw error - } + input = try FetchParam.inputX(inputs: opDesc.inputs, from: inScope) + output = FetchHolder.init(inPaddedCapacity: input.elementCount(), inDim: input.tensorDim) + scope.setOutput(output: output) } //typealias ParamPrecisionType = P @@ -38,21 +34,17 @@ class FetchOp: Operator< FetchKernel

, FetchParam

>, R typealias OpType = FetchOp

func inferShape() { - print(para.input.dim) + paddleMobileLog("\(para.input.dim)") } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print("fetch output: ") - let resArr = self.para.output.result.floatArr(count: self.para.output.capacity) - print(resArr.strideArray()) + let resArr = self.para.output.result?.floatArr(count: self.para.output.capacity) + print(resArr?.strideArray() ?? "") } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/FlattenOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/FlattenOp.swift index 951e572a88..16f2b2ceaa 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/FlattenOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/FlattenOp.swift @@ -17,13 +17,9 @@ import Foundation class FlattenParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try FlattenParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try FlattenParam.outputOut(outputs: opDesc.outputs, from: inScope) + input = try FlattenParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try FlattenParam.outputOut(outputs: opDesc.outputs, from: inScope) // axis = try FlattenParam.getAttr(key: "axis", attrs: opDesc.attrs) - } catch let error { - throw error - } } var input: Texture var output: Texture @@ -40,37 +36,26 @@ class FlattenOp: Operator, FlattenParam

: OpParam { required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try Flatten2Param.inputX(inputs: opDesc.inputs, from: inScope) - output = try Flatten2Param.outputOut(outputs: opDesc.outputs, from: inScope) - - let inDims = input.dim - guard inDims.cout() == 4 else { - fatalError("flatten2 can't handle dims not equal to 4") - } - let outDim = [inDims[0] * inDims[1], inDims[2] * inDims[3]] - output.dim = Dim.init(inDim: outDim) - } catch let error { - throw error + input = try Flatten2Param.inputX(inputs: opDesc.inputs, from: inScope) + output = try Flatten2Param.outputOut(outputs: opDesc.outputs, from: inScope) + + let inDims = input.dim + guard inDims.cout() == 4 else { + throw PaddleMobileError.makeError(type: .netError, msg: "flatten2 can't handle dims not equal to 4") } + let outDim = [inDims[0] * inDims[1], inDims[2] * inDims[3]] + output.dim = Dim.init(inDim: outDim) } var input: Texture var output: Texture @@ -83,17 +68,11 @@ class Flatten2Op: Operator, Flatten2Para } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - let device = para.output.metalTexture!.device - let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose) - print(outputArray.strideArray()) + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Base/Kernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Base/Kernel.swift index 2282fdbb17..2bde861feb 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Base/Kernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Base/Kernel.swift @@ -20,8 +20,8 @@ public protocol TestParam { public protocol Testable { associatedtype TestParamType: TestParam - func test(commandBuffer: MTLCommandBuffer, param: TestParamType) - init(device: MTLDevice, testParam: TestParamType, initContext: InitContext) + func test(commandBuffer: MTLCommandBuffer, param: TestParamType) throws + init(device: MTLDevice, testParam: TestParamType, initContext: InitContext) throws } @@ -39,25 +39,25 @@ protocol KernelProtocol { @objc open class Kernel: NSObject { - private var _pipline: MTLComputePipelineState? = nil + private var _pipline: MTLComputePipelineState? - var pipline: MTLComputePipelineState { + var pipline: MTLComputePipelineState? { get { - return _pipline ?! " pipeline can't be nil " + return _pipline } } let functionName: String? - public init(device: MTLDevice, inFunctionName: String?, usePaddleMobileLib: Bool = false, initContext: InitContext) { + public init(device: MTLDevice, inFunctionName: String?, usePaddleMobileLib: Bool = false, initContext: InitContext) throws { functionName = inFunctionName if let funcName = inFunctionName { - _pipline = device.pipeLine(funcName: funcName, metalLoadMode: initContext.metalLoadMode, metalLibPath: initContext.metalLibPath) + _pipline = try device.pipeLine(funcName: funcName, metalLoadMode: initContext.metalLoadMode, metalLibPath: initContext.metalLibPath) } } func encodeTransposeInput(input: Texture, toTranspose: [Int], commandBuffer: MTLCommandBuffer, device: MTLDevice, initContext: InitContext) -> Texture? { do { - let intermediateTexture = Texture(device: device, inDim: input.tensorDim) + let intermediateTexture = try Texture(device: device, inDim: input.tensorDim) try intermediateTexture.initTexture(device: device, inTranspose: toTranspose, computePrecision: GlobalConfig.shared.computePrecision) let irank = input.tensorDim.cout() @@ -68,14 +68,15 @@ protocol KernelProtocol { } else if GlobalConfig.shared.computePrecision == .Float16 { funcName = "reshape_\(irank)_\(orank)_half" } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } - let intermediatePipeline = device.pipeLine(funcName: funcName, metalLoadMode: initContext.metalLoadMode, metalLibPath: initContext.metalLibPath) - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + let intermediatePipeline = try device.pipeLine(funcName: funcName, metalLoadMode: initContext.metalLoadMode, metalLibPath: initContext.metalLibPath) + guard let inputMetalTexture = input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let interMetalTexture = intermediateTexture.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "intermediateTexture metaltexture is nil") } - encoder.setTexture(input.metalTexture, index: 0) - encoder.setTexture(intermediateTexture.metalTexture, index: 1) var id: [Int32] = [1, 1, 1, 1] for i in 0...size, index: 0) - encoder.dispatch(computePipline: intermediatePipeline, outTexture: intermediateTexture.metalTexture) - encoder.endEncoding() + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(interMetalTexture, index: 1) + encoder.setBytes(&reshapeMetalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: intermediatePipeline, outTexture: interMetalTexture) + } return intermediateTexture } catch _ { return nil @@ -116,43 +126,62 @@ protocol KernelProtocol { open class BufferToTextureKernel: Kernel { public let outputTexture: MTLTexture - public init(device: MTLDevice, outputDim: Shape, metalLoadMode: MetalLoadMode, metalLibPath: String?) { + public init(device: MTLDevice, outputDim: Shape, metalLoadMode: MetalLoadMode, metalLibPath: String?, channelNum: Int) throws { let textureDesc = MTLTextureDescriptor.init() textureDesc.textureType = .type2D textureDesc.width = outputDim.width textureDesc.height = outputDim.height textureDesc.depth = (outputDim.channel + 3) / 4 - if GlobalConfig.shared.computePrecision == .Float16 { textureDesc.pixelFormat = .rgba16Float } else if GlobalConfig.shared.computePrecision == .Float32 { textureDesc.pixelFormat = .rgba32Float } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } - textureDesc.usage = [.shaderRead, .shaderWrite] textureDesc.storageMode = .shared - outputTexture = device.makeTexture(descriptor: textureDesc) ?! " make texture error " + guard let tempTexture = device.makeTexture(descriptor: textureDesc) else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "make texture error") + } + outputTexture = tempTexture let initContext = InitContext.init() initContext.metalLibPath = metalLibPath initContext.metalLoadMode = metalLoadMode if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "buffer_to_texture_kernel", initContext: initContext) + if channelNum == 1 { + try super.init(device: device, inFunctionName: "buffer_to_texture_kernel", initContext: initContext) + } else if channelNum == 3 { + try super.init(device: device, inFunctionName: "buffer_to_texture_kernel_channel_3", initContext: initContext) + } else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "not support channel num: \(channelNum)") + } } else { - super.init(device: device, inFunctionName: "buffer_to_texture_kernel_half", initContext: initContext) + if channelNum == 1 { + try super.init(device: device, inFunctionName: "buffer_to_texture_kernel_half", initContext: initContext) + } else if channelNum == 3 { + try super.init(device: device, inFunctionName: "buffer_to_texture_kernel_half_channel_3", initContext: initContext) + } else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "not support channel num: \(channelNum)") + } } } public func compute(inputBuffer: MTLBuffer , commandBuffer: MTLCommandBuffer) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setBuffer(inputBuffer, offset: 0, index: 0) + encoder.setTexture(outputTexture, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputTexture) } - - encoder.setBuffer(inputBuffer, offset: 0, index: 0) - encoder.setTexture(outputTexture, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: outputTexture) - encoder.endEncoding() } } @@ -160,7 +189,7 @@ open class BufferToTextureKernel: Kernel { @objc open class CusomKernel: Kernel { public let outputTexture: MTLTexture - public init(device: MTLDevice, inFunctionName: String?, outputDim: Shape, metalLoadModel: MetalLoadMode, metalLibPath: String?) { + public init(device: MTLDevice, inFunctionName: String?, outputDim: Shape, metalLoadModel: MetalLoadMode, metalLibPath: String?) throws { let textureDesc = MTLTextureDescriptor.init() textureDesc.textureType = .type2D textureDesc.width = outputDim.width @@ -172,27 +201,37 @@ open class BufferToTextureKernel: Kernel { } else if GlobalConfig.shared.computePrecision == .Float32 { textureDesc.pixelFormat = .rgba32Float } else { - fatalError() + throw PaddleMobileError.makeError(type: .defaultError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } textureDesc.usage = [.shaderRead, .shaderWrite] textureDesc.storageMode = .shared - outputTexture = device.makeTexture(descriptor: textureDesc) ?! " make texture error " + guard let tempTexture = device.makeTexture(descriptor: textureDesc) else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "make texture error") + } + outputTexture = tempTexture let context = InitContext.init() context.metalLoadMode = metalLoadModel context.metalLibPath = metalLibPath - super.init(device: device, inFunctionName: inFunctionName, initContext: context) + try super.init(device: device, inFunctionName: inFunctionName, initContext: context) } public func compute(inputTexuture: MTLTexture, commandBuffer: MTLCommandBuffer) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputTexuture, index: 0) + encoder.setTexture(outputTexture, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputTexture) } - encoder.setTexture(inputTexuture, index: 0) - encoder.setTexture(outputTexture, index: 1) - encoder.dispatch(computePipline: pipline, outTexture: outputTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BatchNormKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BatchNormKernel.swift index 975ef16287..21988570ba 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BatchNormKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BatchNormKernel.swift @@ -22,38 +22,47 @@ class BatchNormKernel: Kernel, Computable { let scaleP = param.scale.data.pointer let biasP = param.bias.data.pointer for i in 0..) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBuffer(param.scale.buffer, offset: 0, index: 0) + encoder.setBuffer(param.bias.buffer, offset: 0, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBuffer(param.scale.buffer, offset: 0, index: 0) - encoder.setBuffer(param.bias.buffer, offset: 0, index: 1) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BilinearInterpKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BilinearInterpKernel.swift index d133918203..aa627d34a8 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BilinearInterpKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BilinearInterpKernel.swift @@ -21,12 +21,15 @@ struct BilinearInterpMetalParam { class BilinearInterpKernel: Kernel, Computable{ func compute(commandBuffer: MTLCommandBuffer, param: BilinearInterpParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) var ratio_h: Float32 = 0 var ratio_w: Float32 = 0 if param.output.tensorDim.dims[2] > 1 { @@ -36,25 +39,30 @@ class BilinearInterpKernel: Kernel, Computable{ ratio_w = Float32(param.input.tensorDim.dims[3]-1) / Float32(param.output.tensorDim.dims[3]-1) } var p = BilinearInterpMetalParam.init(ratio_h: ratio_h, ratio_w: ratio_w) - encoder.setBytes(&p, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&p, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) + } } required init(device: MTLDevice, param: BilinearInterpParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "bilinear_interp_float", initContext: initContext) + try super.init(device: device, inFunctionName: "bilinear_interp_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "bilinear_interp_half", initContext: initContext) + try super.init(device: device, inFunctionName: "bilinear_interp_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BoxcoderKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BoxcoderKernel.swift index 646a08f151..9c920e6da3 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BoxcoderKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/BoxcoderKernel.swift @@ -19,32 +19,47 @@ struct BoxcoderMetalParam { class BoxcoderKernel: Kernel, Computable{ func compute(commandBuffer: MTLCommandBuffer, param: BoxcoderParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let priorBoxMetalTexture = param.priorBox.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "priorBox metaltexture is nil") + } + guard let priorBoxVarMetalTexture = param.priorBoxVar.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "priorBoxVar metaltexture is nil") + } + guard let targetBoxMetalTexture = param.targetBox.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(priorBoxMetalTexture, index: 0) + encoder.setTexture(priorBoxVarMetalTexture, index: 1) + encoder.setTexture(targetBoxMetalTexture, index: 2) + encoder.setTexture(outputMetalTexture, index: 3) + var bmp = BoxcoderMetalParam.init() + encoder.setBytes(&bmp, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(param.priorBox.metalTexture, index: 0) - encoder.setTexture(param.priorBoxVar.metalTexture, index: 1) - encoder.setTexture(param.targetBox.metalTexture, index: 2) - encoder.setTexture(param.output.metalTexture, index: 3) - var bmp = BoxcoderMetalParam.init() - encoder.setBytes(&bmp, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } required init(device: MTLDevice, param: BoxcoderParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: [0, 3, 1, 2], computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: [0, 3, 1, 2], computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "boxcoder_float", initContext: initContext) + try super.init(device: device, inFunctionName: "boxcoder_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "boxcoder_half", initContext: initContext) + try super.init(device: device, inFunctionName: "boxcoder_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConcatKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConcatKernel.swift index 66d9bfd22e..9aeb8949cf 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConcatKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConcatKernel.swift @@ -35,34 +35,44 @@ class ConcatKernel: Kernel, Computable{ var v = "normal" var pm = ConcatMetalParam.init() func compute(commandBuffer: MTLCommandBuffer, param: ConcatParam

) throws { - - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") } - let num = param.input.count - for i in 0...size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setBytes(&pm, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } required init(device: MTLDevice, param: ConcatParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.transpose, computePrecision: GlobalConfig.shared.computePrecision) let orank = param.output.tensorDim.cout() let num = param.input.count - assert(num <= 6) + guard num <= 6 else { + throw PaddleMobileError.makeError(type: .netError, msg: "param input count must be less than or equal to 6") + } var axis = 4 - param.output.tensorDim.cout() + param.axis for i in 0..<4 { if param.transpose[i] == axis { @@ -140,15 +150,15 @@ class ConcatKernel: Kernel, Computable{ } pm.vdim = (Int32(vdim[0]), Int32(vdim[1]), Int32(vdim[2]), Int32(vdim[3]), Int32(vdim[4]), Int32(vdim[5])) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "concat_\(orank)_\(num)_\(v)_float", initContext: initContext) + try super.init(device: device, inFunctionName: "concat_\(orank)_\(num)_\(v)_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "concat_\(orank)_\(num)_\(v)_half", initContext: initContext) + try super.init(device: device, inFunctionName: "concat_\(orank)_\(num)_\(v)_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } - required init(device: MTLDevice, testParam: ConcatTestParam, initContext: InitContext) { - super.init(device: device, inFunctionName: "concat", initContext: initContext) + required init(device: MTLDevice, testParam: ConcatTestParam, initContext: InitContext) throws { + try super.init(device: device, inFunctionName: "concat", initContext: initContext) } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddAddPreluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddAddPreluKernel.swift index 7313837c12..509cdbaaa5 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddAddPreluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddAddPreluKernel.swift @@ -18,114 +18,118 @@ class ConvAddAddPreluKernel: Kernel, Computable { var metalParam: MetalConvParam! required init(device: MTLDevice, param: ConvAddAddPreluParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) - param.y.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) - param.alpha.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.y.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.alpha.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float16 { if param.filter.width == 1 && param.filter.height == 1 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_half", initContext: initContext) - } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_half", initContext: initContext) - } else { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_half", initContext: initContext) - } - - } else if param.filter.channel == 1 { - if param.mode == "channel" { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_half", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_half", initContext: initContext) } } else if param.filter.width == 3 && param.filter.height == 3 { - if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_half", initContext: initContext) - } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_half", initContext: initContext) + if param.filter.channel == 1 { + if param.mode == "channel" { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_half", initContext: initContext) + } else if param.mode == "element" { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_half", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_half", initContext: initContext) + } } else { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_half", initContext: initContext) + if param.mode == "channel" { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_half", initContext: initContext) + } else if param.mode == "element" { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_half", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_half", initContext: initContext) + } } - } else if param.filter.width == 1 && param.filter.height == 5 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_half", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_half", initContext: initContext) } } else if param.filter.width == 5 && param.filter.height == 1 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_half", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_half", initContext: initContext) } } else { - fatalError(" unsupport yet ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported conv filter") } } else if GlobalConfig.shared.computePrecision == .Float32 { if param.filter.width == 1 && param.filter.height == 1 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_float", initContext: initContext) - } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_float", initContext: initContext) - } else { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_float", initContext: initContext) - } - } else if param.filter.channel == 1 { - if param.mode == "channel" { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_float", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_float", initContext: initContext) } else { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_float", initContext: initContext) } } else if param.filter.width == 3 && param.filter.height == 3 { - if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_float", initContext: initContext) - } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_float", initContext: initContext) + if param.filter.channel == 1 { + if param.mode == "channel" { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_float", initContext: initContext) + } else if param.mode == "element" { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_float", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_float", initContext: initContext) + } } else { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_float", initContext: initContext) + if param.mode == "channel" { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_float", initContext: initContext) + } else if param.mode == "element" { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_float", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_float", initContext: initContext) + } } - } else if param.filter.width == 1 && param.filter.height == 5 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_float", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_float", initContext: initContext) } else { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_float", initContext: initContext) } } else if param.filter.width == 5 && param.filter.height == 1 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_float", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_float", initContext: initContext) } else { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_float", initContext: initContext) } } else { - fatalError(" unsupport yet ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported conv filter") } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") + } + + guard let filterHeight = param.filter.height else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") + } + guard let filterWidth = param.filter.width else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") } - let offsetY = (Int(param.dilations[1]) * (param.filter.height - 1) + 1)/2 - Int(param.paddings[1]) + let offsetY = (Int(param.dilations[1]) * (filterHeight - 1) + 1)/2 - Int(param.paddings[1]) - let offsetX = (Int(param.dilations[0]) * (param.filter.width - 1) + 1)/2 - Int(param.paddings[0]) + let offsetX = (Int(param.dilations[0]) * (filterWidth - 1) + 1)/2 - Int(param.paddings[0]) // print(" function: \(functionName)") // print("offset x: \(offsetX)") @@ -143,17 +147,29 @@ class ConvAddAddPreluKernel: Kernel, Computable { } func compute(commandBuffer: MTLCommandBuffer, param: ConvAddAddPreluParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) + encoder.setBuffer(param.y.buffer, offset: 0, index: 2) + encoder.setBuffer(param.alpha.buffer, offset: 0, index: 3) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) - encoder.setBuffer(param.y.buffer, offset: 0, index: 2) - encoder.setBuffer(param.alpha.buffer, offset: 0, index: 3) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddBatchNormReluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddBatchNormReluKernel.swift index a10e1939df..cc2d730fd4 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddBatchNormReluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddBatchNormReluKernel.swift @@ -37,13 +37,17 @@ struct ConvAddBatchNormReluTestParam: TestParam { } class ConvAddBatchNormReluKernel: Kernel, Computable, Testable { - required init(device: MTLDevice, testParam: ConvAddBatchNormReluTestParam, initContext: InitContext) { + required init(device: MTLDevice, testParam: ConvAddBatchNormReluTestParam, initContext: InitContext) throws { if testParam.filterSize.width == 1 && testParam.filterSize.height == 1 { - super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_1x1", initContext: initContext) - } else if testParam.filterSize.channel == 1 { - super.init(device: device, inFunctionName: "depthwise_conv_add_batch_norm_relu_3x3", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_1x1", initContext: initContext) + } else if testParam.filterSize.width == 3 && testParam.filterSize.height == 3 { + if testParam.filterSize.channel == 1 { + try super.init(device: device, inFunctionName: "depthwise_conv_add_batch_norm_relu_3x3", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_3x3", initContext: initContext) + } } else { - super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_3x3", initContext: initContext) + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported conv filter") } } @@ -51,48 +55,54 @@ class ConvAddBatchNormReluKernel: Kernel, Computable, Test required init(device: MTLDevice, param: ConvAddBatchNormReluParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) - param.y.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) - param.variance.initBuffer(device: device, precision: .Float32) - param.mean.initBuffer(device: device, precision: .Float32) - param.scale.initBuffer(device: device, precision: .Float32) - param.bias.initBuffer(device: device, precision: .Float32) + try param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.y.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.variance.initBuffer(device: device, precision: .Float32) + try param.mean.initBuffer(device: device, precision: .Float32) + try param.scale.initBuffer(device: device, precision: .Float32) + try param.bias.initBuffer(device: device, precision: .Float32) if GlobalConfig.shared.computePrecision == .Float32 { if param.filter.width == 1 && param.filter.height == 1 { - super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_1x1", initContext: initContext) - } else if param.filter.channel == 1 { - super.init(device: device, inFunctionName: "depthwise_conv_add_batch_norm_relu_3x3", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_1x1", initContext: initContext) } else if param.filter.width == 3 && param.filter.height == 3 { - super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_3x3", initContext: initContext) + if param.filter.channel == 1 { + try super.init(device: device, inFunctionName: "depthwise_conv_add_batch_norm_relu_3x3", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_3x3", initContext: initContext) + } } else { - fatalError(" unsupport ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported conv filter") } } else if GlobalConfig.shared.computePrecision == .Float16 { if param.filter.width == 1 && param.filter.height == 1 { - super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_1x1_half", initContext: initContext) - } else if param.filter.channel == 1 { - super.init(device: device, inFunctionName: "depthwise_conv_add_batch_norm_relu_3x3_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_1x1_half", initContext: initContext) } else if param.filter.width == 3 && param.filter.height == 3 { - super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_3x3_half", initContext: initContext) + if param.filter.channel == 1 { + try super.init(device: device, inFunctionName: "depthwise_conv_add_batch_norm_relu_3x3_half", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_add_batch_norm_relu_3x3_half", initContext: initContext) + } } else { - fatalError(" unsupport ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported conv filter") } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } - let offsetX = param.filter.width/2 - Int(param.paddings[0]) - let offsetY = param.filter.height/2 - Int(param.paddings[1]) + guard let filterWidth = param.filter.width else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") + } + guard let filterHeight = param.filter.height else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") + } + let offsetX = filterWidth/2 - Int(param.paddings[0]) + let offsetY = filterHeight/2 - Int(param.paddings[1]) - print("offset x: \(offsetX)") - print("offset y: \(offsetY)") + paddleMobileLog("offset x: \(offsetX)") + paddleMobileLog("offset y: \(offsetY)") let offsetZ = 0.0 let iC = param.input.tensorDim[1]; @@ -104,13 +114,19 @@ class ConvAddBatchNormReluKernel: Kernel, Computable, Test let varianceContents = param.variance.buffer.contents().assumingMemoryBound(to: P.self) for i in 0...stride { - let inv = 1.0/pow(Float32.init(varianceContents[i]) + param.epsilon, 0.5) - invs.append(P(inv)) + let inv = 1.0/pow(try Float32.init(varianceContents[i]) + param.epsilon, 0.5) + invs.append(try P(inv)) } let newScale: UnsafeMutablePointer

= UnsafeMutablePointer

.allocate(capacity: param.scale.buffer.length) let newBiase: UnsafeMutablePointer

= UnsafeMutablePointer

.allocate(capacity: param.bias.buffer.length) - + defer { + newScale.deinitialize(count: param.scale.buffer.length) + newScale.deallocate() + + newBiase.deinitialize(count: param.bias.buffer.length) + newBiase.deallocate() + } let scaleContents = param.scale.buffer.contents().assumingMemoryBound(to: P.self) let biaseContents = param.bias.buffer.contents().assumingMemoryBound(to: P.self) let meanContents = param.mean.buffer.contents().assumingMemoryBound(to: P.self) @@ -137,53 +153,65 @@ class ConvAddBatchNormReluKernel: Kernel, Computable, Test newBiaseBuffer = device.makeBuffer(length: param.bias.buffer.length / 2)! newScaleBuffer = device.makeBuffer(length: param.bias.buffer.length / 2)! - float32ToFloat16(input: newBiase as! UnsafeMutablePointer, output: newBiaseBuffer.contents(), count: param.bias.buffer.length / MemoryLayout

.size) + try float32ToFloat16(input: newBiase as! UnsafeMutablePointer, output: newBiaseBuffer.contents(), count: param.bias.buffer.length / MemoryLayout

.size) - float32ToFloat16(input: newScale as! UnsafeMutablePointer, output: newScaleBuffer.contents(), count: param.scale.buffer.length / MemoryLayout

.size) + try float32ToFloat16(input: newScale as! UnsafeMutablePointer, output: newScaleBuffer.contents(), count: param.scale.buffer.length / MemoryLayout

.size) } else { - fatalError(" unsupport ") + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } param.newBiase = newBiaseBuffer param.newScale = newScaleBuffer - - newScale.deinitialize(count: param.scale.buffer.length) - newScale.deallocate() - - newBiase.deinitialize(count: param.bias.buffer.length) - newBiase.deallocate() } func compute(commandBuffer: MTLCommandBuffer, param: ConvAddBatchNormReluParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputTexture, index: 0) + encoder.setTexture(outputTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) + encoder.setBuffer(param.y.buffer, offset: 0, index: 2) + encoder.setBuffer(param.newScale!, offset: 0, index: 3) + encoder.setBuffer(param.newBiase!, offset: 0, index: 4) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) - encoder.setBuffer(param.y.buffer, offset: 0, index: 2) - encoder.setBuffer(param.newScale!, offset: 0, index: 3) - encoder.setBuffer(param.newBiase!, offset: 0, index: 4) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } - public func test(commandBuffer: MTLCommandBuffer, param: ConvAddBatchNormReluTestParam) { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - fatalError() + public func test(commandBuffer: MTLCommandBuffer, param: ConvAddBatchNormReluTestParam) throws { + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "pipline nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "encoder nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(param.inputTexture, index: 0) + encoder.setTexture(param.outputTexture, index: 1) + var inMetalParam = param.metalParam + encoder.setBytes(&inMetalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filterBuffer, offset: 0, index: 1) + encoder.setBuffer(param.biaseBuffer, offset: 0, index: 2) + encoder.setBuffer(param.newScaleBuffer, offset: 0, index: 3) + encoder.setBuffer(param.newBiaseBuffer, offset: 0, index: 4) + try encoder.dispatch(computePipline: tempPipline, outTexture: param.outputTexture) } - - encoder.setTexture(param.inputTexture, index: 0) - encoder.setTexture(param.outputTexture, index: 1) - var inMetalParam = param.metalParam - encoder.setBytes(&inMetalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filterBuffer, offset: 0, index: 1) - encoder.setBuffer(param.biaseBuffer, offset: 0, index: 2) - encoder.setBuffer(param.newScaleBuffer, offset: 0, index: 3) - encoder.setBuffer(param.newBiaseBuffer, offset: 0, index: 4) - encoder.dispatch(computePipline: pipline, outTexture: param.outputTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddKernel.swift index eefffd817a..79dfd6f754 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddKernel.swift @@ -19,7 +19,7 @@ class ConvAddKernel: ConvAddReluKernel

{ override class func hasAddOp() -> Bool { return true } - + override class func hasReluOp() -> Bool { return false } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddPreluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddPreluKernel.swift index 6c6f926162..d3fba8df26 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddPreluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddPreluKernel.swift @@ -18,114 +18,118 @@ class ConvAddPreluKernel: Kernel, Computable { var metalParam: MetalConvParam! required init(device: MTLDevice, param: ConvAddPreluParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) - param.y.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) - param.alpha.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.y.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.alpha.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float16 { if param.filter.width == 1 && param.filter.height == 1 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_half", initContext: initContext) - } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_half", initContext: initContext) - } else { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_half", initContext: initContext) - } - - } else if param.filter.channel == 1 { - if param.mode == "channel" { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_half", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_half", initContext: initContext) } } else if param.filter.width == 3 && param.filter.height == 3 { - if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_half", initContext: initContext) - } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_half", initContext: initContext) + if param.filter.channel == 1 { + if param.mode == "channel" { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_half", initContext: initContext) + } else if param.mode == "element" { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_half", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_half", initContext: initContext) + } } else { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_half", initContext: initContext) + if param.mode == "channel" { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_half", initContext: initContext) + } else if param.mode == "element" { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_half", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_half", initContext: initContext) + } } - } else if param.filter.width == 1 && param.filter.height == 5 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_half", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_half", initContext: initContext) } } else if param.filter.width == 5 && param.filter.height == 1 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_half", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_half", initContext: initContext) } } else { - fatalError(" unsupport yet ") + throw PaddleMobileError.makeError(type: .paramError, msg: "unsupported filter") } } else if GlobalConfig.shared.computePrecision == .Float32 { if param.filter.width == 1 && param.filter.height == 1 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_float", initContext: initContext) - } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_float", initContext: initContext) - } else { - super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_float", initContext: initContext) - } - } else if param.filter.channel == 1 { - if param.mode == "channel" { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_float", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_float", initContext: initContext) } else { - super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_float", initContext: initContext) } } else if param.filter.width == 3 && param.filter.height == 3 { - if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_float", initContext: initContext) - } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_float", initContext: initContext) + if param.filter.channel == 1 { + if param.mode == "channel" { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_float", initContext: initContext) + } else if param.mode == "element" { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_float", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_float", initContext: initContext) + } } else { - super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_float", initContext: initContext) + if param.mode == "channel" { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_float", initContext: initContext) + } else if param.mode == "element" { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_float", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_float", initContext: initContext) + } } - } else if param.filter.width == 1 && param.filter.height == 5 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_float", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_float", initContext: initContext) } else { - super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_float", initContext: initContext) } } else if param.filter.width == 5 && param.filter.height == 1 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_float", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_float", initContext: initContext) } else { - super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_float", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_float", initContext: initContext) } } else { - fatalError(" unsupport yet ") + throw PaddleMobileError.makeError(type: .paramError, msg: "unsupported filter") } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") + } + + guard let filterHeight = param.filter.height else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") + } + guard let filterWidth = param.filter.width else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") } - let offsetY = (Int(param.dilations[1]) * (param.filter.height - 1) + 1)/2 - Int(param.paddings[1]) + let offsetY = (Int(param.dilations[1]) * (filterHeight - 1) + 1)/2 - Int(param.paddings[1]) - let offsetX = (Int(param.dilations[0]) * (param.filter.width - 1) + 1)/2 - Int(param.paddings[0]) + let offsetX = (Int(param.dilations[0]) * (filterWidth - 1) + 1)/2 - Int(param.paddings[0]) // print(" function: \(functionName)") // print("offset x: \(offsetX)") @@ -143,17 +147,29 @@ class ConvAddPreluKernel: Kernel, Computable { } func compute(commandBuffer: MTLCommandBuffer, param: ConvAddPreluParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) + encoder.setBuffer(param.y.buffer, offset: 0, index: 2) + encoder.setBuffer(param.alpha.buffer, offset: 0, index: 3) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) - encoder.setBuffer(param.y.buffer, offset: 0, index: 2) - encoder.setBuffer(param.alpha.buffer, offset: 0, index: 3) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddReluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddReluKernel.swift index 4b742f94d5..28b78cfe1c 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddReluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvAddReluKernel.swift @@ -34,59 +34,64 @@ public struct MetalConvParam { @available(iOS 11.0, *) class ConvDataSource: NSObject, MPSCNNConvolutionDataSource { + var _descriptor: MPSCNNConvolutionDescriptor var _weightsTensor: Tensor

var _biasTensor: Tensor

? var _biasTerms: UnsafeMutablePointer? - + func load() -> Bool { - if let biasTensor = _biasTensor { - switch P.precisionType { - case .Float32: - _biasTerms = biasTensor.data.pointer as? UnsafeMutablePointer - case .Float16: - _biasTerms = UnsafeMutablePointer.allocate(capacity: biasTensor.data.count) - if let float16Point = biasTensor.data.pointer as? UnsafeMutablePointer { - float16to32(input: float16Point, output: _biasTerms!, count: biasTensor.data.count) - } - } - } return true } - + func purge() { - switch P.precisionType { - case .Float32: - return - case .Float16: - if let biasTensor = _biasTensor { - _biasTerms?.deinitialize(count: biasTensor.data.count) - _biasTerms?.deallocate() - } - } + } - + func label() -> String? { return "conv_add_relu_label" } - + func copy(with zone: NSZone? = nil) -> Any { return self } - + init(inDesc: MPSCNNConvolutionDescriptor, inWeights: Tensor

, - inBiasTerms: Tensor

?) { + inBiasTerms: Tensor

?) throws { _descriptor = inDesc _weightsTensor = inWeights _biasTensor = inBiasTerms + if let tempBiasTensor = _biasTensor { + switch P.precisionType { + case .Float32: + if let tempBiasTerms = tempBiasTensor.data.pointer as? UnsafeMutablePointer { + _biasTerms = tempBiasTerms + } else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "_biasTensor.data.pointer not UnsafeMutablePointer") + } + case .Float16: + _biasTerms = UnsafeMutablePointer.allocate(capacity: tempBiasTensor.data.count) + do { + if let float16Point = tempBiasTensor.data.pointer as? UnsafeMutablePointer { + try float16to32(input: float16Point, output: _biasTerms!, count: tempBiasTensor.data.count) + } else { + throw PaddleMobileError.makeError(type: .loaderError, msg: "_biasTensor.data.pointer not UnsafeMutablePointer") + } + } catch let error { + _biasTerms?.deallocate() + _biasTerms = nil + throw error + } + } + } super.init() } - + func descriptor() -> MPSCNNConvolutionDescriptor { return _descriptor } - + func dataType() -> MPSDataType { switch P.precisionType { case .Float32: @@ -95,14 +100,23 @@ class ConvDataSource: NSObject, MPSCNNConvolutionDataSourc return .float16 } } - + func weights() -> UnsafeMutableRawPointer { return UnsafeMutableRawPointer.init(_weightsTensor.data.pointer) } - + func biasTerms() -> UnsafeMutablePointer? { return _biasTerms } + + deinit { + switch P.precisionType { + case .Float32: + break + case .Float16: + _biasTerms?.deallocate() + } + } } @@ -142,14 +156,14 @@ class ConvAddReluKernel: Kernel, Computable { } } if shouldUseMPS { - super.init(device: device, inFunctionName: nil, initContext: initContext) - setupWithMPS(device: device, param: param) + try super.init(device: device, inFunctionName: nil, initContext: initContext) + try setupWithMPS(device: device, param: param) } else { if functionName == nil { fatalError(" unsupport yet ") } - super.init(device: device, inFunctionName: functionName, initContext: initContext) - setupWithoutMPS(device: device, param: param) + try super.init(device: device, inFunctionName: functionName, initContext: initContext) + try setupWithoutMPS(device: device, param: param) } } @@ -157,19 +171,29 @@ class ConvAddReluKernel: Kernel, Computable { var outputImage: AnyObject? func compute(commandBuffer: MTLCommandBuffer, param: ConvAddReluParam

) throws { + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } if #available(iOS 10.0, *) { if let conv = mpsConvOp as? MPSCNNConvolution { if inputImage == nil { - inputImage = MPSImage.init(texture: param.input.metalTexture, featureChannels: param.input.tensorDim[1]) + inputImage = MPSImage.init(texture: inputMetalTexture, featureChannels: param.input.tensorDim[1]) } if outputImage == nil { - outputImage = MPSImage.init(texture: param.output.metalTexture, featureChannels: param.output.tensorDim[1]) + outputImage = MPSImage.init(texture: outputMetalTexture, featureChannels: param.output.tensorDim[1]) } + if let inputImage = inputImage as? MPSImage, let outputImage = outputImage as? MPSImage { conv.encode(commandBuffer: commandBuffer, sourceImage: inputImage, destinationImage: outputImage) if #available(iOS 11.3, *) { if let add = mpsAddOp as? MPSCNNAdd, let y = param.y { - let biasImage = MPSImage.init(texture: y.metalTexture, featureChannels: y.tensorDim[1]) + guard let yMetalTexture = y.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "y metaltexture is nil") + } + let biasImage = MPSImage.init(texture: yMetalTexture, featureChannels: y.tensorDim[1]) add.encode(commandBuffer: commandBuffer, primaryImage: outputImage, secondaryImage: biasImage, destinationImage: outputImage) } if let relu = mpsReluOp as? MPSCNNNeuronReLU { @@ -180,19 +204,26 @@ class ConvAddReluKernel: Kernel, Computable { return } } - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(param.y?.metalTexture, index: 1) + encoder.setTexture(outputMetalTexture, index: 2) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture, groupDepth: type(of: self).isWinoGrad(functionName: functionName) ? 1 : nil) } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.y?.metalTexture, index: 1) - encoder.setTexture(param.output.metalTexture, index: 2) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture, groupDepth: type(of: self).isWinoGrad(functionName: functionName) ? 1 : nil) - encoder.endEncoding() } - func setupWithMPS(device: MTLDevice, param: ConvAddReluParam

) { + func setupWithMPS(device: MTLDevice, param: ConvAddReluParam

) throws { let offsetX = (Int(param.dilations[0]) * (param.filter.tensorDim[3] - 1) + 1) / 2 - Int(param.paddings[0]) let offsetY = (Int(param.dilations[1]) * (param.filter.tensorDim[2] - 1) + 1) / 2 - Int(param.paddings[1]) @@ -222,12 +253,12 @@ class ConvAddReluKernel: Kernel, Computable { neuronFilter: neuronFilter) desc.strideInPixelsX = Int(param.stride[0]) desc.strideInPixelsY = Int(param.stride[1]) - let _ = param.filter.convert(converter: MPSPointerConverter

.init()) + let _ = try param.filter.convert(converter: MPSPointerConverter

.init()) var biasTerms: Tensor

? = nil if type(of: self).hasAddOp() && type(of: self).canMPSAddByChannel(param: param) { biasTerms = param.yTensor } - let dataSource = ConvDataSource.init(inDesc: desc, inWeights: param.filter, inBiasTerms: biasTerms) + let dataSource = try ConvDataSource.init(inDesc: desc, inWeights: param.filter, inBiasTerms: biasTerms) let conv = MPSCNNConvolution.init(device: device, weights: dataSource) conv.offset = MPSOffset.init(x: offsetX, y: offsetY, z: 0) @@ -236,7 +267,7 @@ class ConvAddReluKernel: Kernel, Computable { } } - func setupWithoutMPS(device: MTLDevice, param: ConvAddReluParam

) { + func setupWithoutMPS(device: MTLDevice, param: ConvAddReluParam

) throws { let offsetX = (Int(param.dilations[0]) * (param.filter.tensorDim[3] - 1) + 1) / 2 - Int(param.paddings[0]) let offsetY = (Int(param.dilations[1]) * (param.filter.tensorDim[2] - 1) + 1) / 2 - Int(param.paddings[1]) let offsetZ = 0.0 @@ -251,16 +282,16 @@ class ConvAddReluKernel: Kernel, Computable { metalParam = inMetalParam if type(of: self).isWinoGrad(functionName: functionName) { - let _ = param.filter.convert(converter: WinogradPointerConverter

.init()) + let _ = try param.filter.convert(converter: WinogradPointerConverter

.init()) } let padWhenOneC = !(param.filter.channel == 1 && param.filter.n == param.input.tensorDim[1]) - param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision, padWhenOneC: padWhenOneC) + try param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision, padWhenOneC: padWhenOneC) if param.y == nil { let blankTensor = Tensor

.init(inDim: Dim(inDim: [1, 1, 1, 4]), inLayout: DataLayout.NHWC(), originDimsCount: 4) - blankTexture = Texture.init(device: device, inDim: blankTensor.dim) - let value:[P] = [P(Float32(1.0)), P(Float32(1.0)), P(Float32(1.0)), P(Float32(1.0)),] - blankTexture?.metalTexture = device.tensor2texture(value: value, dim: blankTensor.dim.dims, transpose: [0, 2, 3, 1], inComputePrecision: GlobalConfig.shared.computePrecision) + blankTexture = try Texture.init(device: device, inDim: blankTensor.dim) + let value:[P] = try [P(Float32(1.0)), P(Float32(1.0)), P(Float32(1.0)), P(Float32(1.0)),] + blankTexture?.metalTexture = try device.tensor2texture(value: value, dim: blankTensor.dim.dims, transpose: [0, 2, 3, 1], inComputePrecision: GlobalConfig.shared.computePrecision) } } @@ -268,23 +299,23 @@ class ConvAddReluKernel: Kernel, Computable { if GlobalConfig.shared.computePrecision == .Float16 { if param.filter.width == 1 && param.filter.height == 1 { return "conv_add_relu_1x1_half" - } - if param.filter.channel == 1 && param.filter.n == param.input.tensorDim[1] { - if useAggressiveOptimization { - let couldUseWinograd = param.filter.width == 3 && param.filter.height == 3 - && param.filter.n <= 16 && param.stride[0] == 1 && param.stride[1] == 1 - && param.dilations[0] == 1 && param.dilations[1] == 1 - if couldUseWinograd { - return "depthwise_conv_add_relu_3x3_half_winograd" + } else if param.filter.width == 3 && param.filter.height == 3 { + if param.filter.channel == 1 && param.filter.n == param.input.tensorDim[1] { + if useAggressiveOptimization { + let couldUseWinograd = param.filter.width == 3 && param.filter.height == 3 + && (param.filter.n ?? Int.max) <= 16 && param.stride[0] == 1 && param.stride[1] == 1 + && param.dilations[0] == 1 && param.dilations[1] == 1 + if couldUseWinograd { + return "depthwise_conv_add_relu_3x3_half_winograd" + } } - } - return "depthwise_conv_add_relu_3x3_half" - } - if param.filter.width == 3 && param.filter.height == 3 { - if param.groups == 1 { - return "conv_add_relu_3x3_half" + return "depthwise_conv_add_relu_3x3_half" } else { - return "group_conv_add_relu_3x3_half" + if param.groups == 1 { + return "conv_add_relu_3x3_half" + } else { + return "group_conv_add_relu_3x3_half" + } } } if param.filter.width == 1 && param.filter.height == 5 { @@ -297,18 +328,20 @@ class ConvAddReluKernel: Kernel, Computable { } else if GlobalConfig.shared.computePrecision == .Float32 { if param.filter.width == 1 && param.filter.height == 1 { return "conv_add_relu_1x1" - } else if param.filter.channel == 1 && param.filter.n == param.input.tensorDim[1] { - return "depthwise_conv_add_relu_3x3" + } else if param.filter.width == 3 && param.filter.height == 3 { + if param.filter.channel == 1 && param.filter.n == param.input.tensorDim[1] { + return "depthwise_conv_add_relu_3x3" + } else { + if param.groups == 1 { + return "conv_add_relu_3x3" + } else { + return "group_conv_add_relu_3x3" + } + } } else if param.filter.width == 1 && param.filter.height == 5 { return "conv_add_relu_5x1" } else if param.filter.width == 5 && param.filter.height == 1 { return "conv_add_relu_1x5" - } else if param.filter.width == 3 && param.filter.height == 3 { - if param.groups == 1 { - return "conv_add_relu_3x3" - } else { - return "group_conv_add_relu_3x3" - } } else { return nil } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvBNReluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvBNReluKernel.swift index d70caca5f4..c5ff740bb0 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvBNReluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvBNReluKernel.swift @@ -38,13 +38,17 @@ struct ConvBNReluTestParam: TestParam { } class ConvBNReluKernel: Kernel, Computable, Testable { - required init(device: MTLDevice, testParam: ConvBNReluTestParam, initContext: InitContext) { + required init(device: MTLDevice, testParam: ConvBNReluTestParam, initContext: InitContext) throws { if testParam.filterSize.width == 1 && testParam.filterSize.height == 1 { - super.init(device: device, inFunctionName: "conv_batch_norm_relu_1x1", initContext: initContext) - } else if testParam.filterSize.channel == 1 { - super.init(device: device, inFunctionName: "depthwise_conv_batch_norm_relu_3x3", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_batch_norm_relu_1x1", initContext: initContext) + } else if testParam.filterSize.width == 3 && testParam.filterSize.height == 3 { + if testParam.filterSize.channel == 1 { + try super.init(device: device, inFunctionName: "depthwise_conv_batch_norm_relu_3x3", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_batch_norm_relu_3x3", initContext: initContext) + } } else { - super.init(device: device, inFunctionName: "conv_batch_norm_relu_3x3", initContext: initContext) + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported conv filter") } } @@ -52,46 +56,51 @@ class ConvBNReluKernel: Kernel, Computable, Testable { required init(device: MTLDevice, param: ConvBNReluParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) - param.variance.initBuffer(device: device, precision: .Float32) - param.mean.initBuffer(device: device, precision: .Float32) - param.scale.initBuffer(device: device, precision: .Float32) - param.bias.initBuffer(device: device, precision: .Float32) + try param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.variance.initBuffer(device: device, precision: .Float32) + try param.mean.initBuffer(device: device, precision: .Float32) + try param.scale.initBuffer(device: device, precision: .Float32) + try param.bias.initBuffer(device: device, precision: .Float32) if GlobalConfig.shared.computePrecision == .Float32 { if param.filter.width == 1 && param.filter.height == 1 { - super.init(device: device, inFunctionName: "conv_batch_norm_relu_1x1", initContext: initContext) - } else if param.filter.channel == 1 { - super.init(device: device, inFunctionName: "depthwise_conv_batch_norm_relu_3x3", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_batch_norm_relu_1x1", initContext: initContext) } else if param.filter.width == 3 && param.filter.height == 3 { - super.init(device: device, inFunctionName: "conv_batch_norm_relu_3x3", initContext: initContext) + if param.filter.channel == 1 { + try super.init(device: device, inFunctionName: "depthwise_conv_batch_norm_relu_3x3", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_batch_norm_relu_3x3", initContext: initContext) + } } else { - fatalError(" unsupport ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported conv filter") } } else if GlobalConfig.shared.computePrecision == .Float16 { if param.filter.width == 1 && param.filter.height == 1 { - super.init(device: device, inFunctionName: "conv_batch_norm_relu_1x1_half", initContext: initContext) - } else if param.filter.channel == 1 { - super.init(device: device, inFunctionName: "depthwise_conv_batch_norm_relu_3x3_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_batch_norm_relu_1x1_half", initContext: initContext) } else if param.filter.width == 3 && param.filter.height == 3 { - super.init(device: device, inFunctionName: "conv_batch_norm_relu_3x3_half", initContext: initContext) + if param.filter.channel == 1 { + try super.init(device: device, inFunctionName: "depthwise_conv_batch_norm_relu_3x3_half", initContext: initContext) + } else { + try super.init(device: device, inFunctionName: "conv_batch_norm_relu_3x3_half", initContext: initContext) + } } else { - fatalError(" unsupport ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported conv filter") } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } + guard let filterHeight = param.filter.height else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") + } + guard let filterWidth = param.filter.width else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") + } - - let offsetX = param.filter.width/2 - Int(param.paddings[0]) - let offsetY = param.filter.height/2 - Int(param.paddings[1]) + let offsetX = filterWidth/2 - Int(param.paddings[0]) + let offsetY = filterHeight/2 - Int(param.paddings[1]) // print(" param filter width: \(param.filter.width)") // print(" param filter height: \(param.filter.height)") @@ -111,13 +120,19 @@ class ConvBNReluKernel: Kernel, Computable, Testable { let varianceContents = param.variance.buffer.contents().assumingMemoryBound(to: P.self) for i in 0...stride { - let inv = 1.0/pow(Float32.init(varianceContents[i]) + param.epsilon, 0.5) - invs.append(P(inv)) + let inv = 1.0/pow((try Float32.init(varianceContents[i])) + param.epsilon, 0.5) + invs.append(try P(inv)) } let newScale: UnsafeMutablePointer

= UnsafeMutablePointer

.allocate(capacity: param.scale.buffer.length) let newBiase: UnsafeMutablePointer

= UnsafeMutablePointer

.allocate(capacity: param.bias.buffer.length) - + defer { + newScale.deinitialize(count: param.scale.buffer.length) + newScale.deallocate() + + newBiase.deinitialize(count: param.bias.buffer.length) + newBiase.deallocate() + } let scaleContents = param.scale.buffer.contents().assumingMemoryBound(to: P.self) let biaseContents = param.bias.buffer.contents().assumingMemoryBound(to: P.self) let meanContents = param.mean.buffer.contents().assumingMemoryBound(to: P.self) @@ -137,51 +152,63 @@ class ConvBNReluKernel: Kernel, Computable, Testable { newBiaseBuffer = device.makeBuffer(length: param.bias.buffer.length / 2)! newScaleBuffer = device.makeBuffer(length: param.bias.buffer.length / 2)! - float32ToFloat16(input: newBiase as! UnsafeMutablePointer, output: newBiaseBuffer.contents(), count: param.bias.buffer.length / MemoryLayout

.size) + try float32ToFloat16(input: newBiase as! UnsafeMutablePointer, output: newBiaseBuffer.contents(), count: param.bias.buffer.length / MemoryLayout

.size) - float32ToFloat16(input: newScale as! UnsafeMutablePointer, output: newScaleBuffer.contents(), count: param.scale.buffer.length / MemoryLayout

.size) + try float32ToFloat16(input: newScale as! UnsafeMutablePointer, output: newScaleBuffer.contents(), count: param.scale.buffer.length / MemoryLayout

.size) } else { - fatalError(" unsupport ") + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } param.newBiase = newBiaseBuffer param.newScale = newScaleBuffer - - newScale.deinitialize(count: param.scale.buffer.length) - newScale.deallocate() - - newBiase.deinitialize(count: param.bias.buffer.length) - newBiase.deallocate() } func compute(commandBuffer: MTLCommandBuffer, param: ConvBNReluParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) + encoder.setBuffer(param.newScale!, offset: 0, index: 2) + encoder.setBuffer(param.newBiase!, offset: 0, index: 3) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) - encoder.setBuffer(param.newScale!, offset: 0, index: 2) - encoder.setBuffer(param.newBiase!, offset: 0, index: 3) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } - public func test(commandBuffer: MTLCommandBuffer, param: ConvBNReluTestParam) { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - fatalError() + public func test(commandBuffer: MTLCommandBuffer, param: ConvBNReluTestParam) throws { + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "pipline nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .defaultError, msg: "encoder nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(param.inputTexture, index: 0) + encoder.setTexture(param.outputTexture, index: 1) + var inMetalParam = param.metalParam + encoder.setBytes(&inMetalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filterBuffer, offset: 0, index: 1) + encoder.setBuffer(param.newScaleBuffer, offset: 0, index: 2) + encoder.setBuffer(param.newBiaseBuffer, offset: 0, index: 3) + try encoder.dispatch(computePipline: tempPipline, outTexture: param.outputTexture) } - - encoder.setTexture(param.inputTexture, index: 0) - encoder.setTexture(param.outputTexture, index: 1) - var inMetalParam = param.metalParam - encoder.setBytes(&inMetalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filterBuffer, offset: 0, index: 1) - encoder.setBuffer(param.newScaleBuffer, offset: 0, index: 2) - encoder.setBuffer(param.newBiaseBuffer, offset: 0, index: 3) - encoder.dispatch(computePipline: pipline, outTexture: param.outputTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvKernel.swift index 19dc193ac4..8255790ac1 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvKernel.swift @@ -42,39 +42,52 @@ class ConvKernel: Kernel, Computable { shouldUseMPS = false } if shouldUseMPS { - super.init(device: device, inFunctionName: nil, initContext: initContext) - setupWithMPS(device: device, param: param) + try super.init(device: device, inFunctionName: nil, initContext: initContext) + try setupWithMPS(device: device, param: param) } else { if functionName == nil { fatalError(" unsupport yet ") } - super.init(device: device, inFunctionName: functionName, initContext: initContext) - setupWithoutMPS(device: device, param: param) + try super.init(device: device, inFunctionName: functionName, initContext: initContext) + try setupWithoutMPS(device: device, param: param) } } func compute(commandBuffer: MTLCommandBuffer, param: ConvParam

) throws { + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } if #available(iOS 10.0, *) { if let conv = mpsConvOp as? MPSCNNConvolution { - let inputImage = MPSImage.init(texture: param.input.metalTexture, featureChannels: param.input.tensorDim[1]) - let outputImage = MPSImage.init(texture: param.output.metalTexture, featureChannels: param.output.tensorDim[1]) + let inputImage = MPSImage.init(texture: inputMetalTexture, featureChannels: param.input.tensorDim[1]) + let outputImage = MPSImage.init(texture: outputMetalTexture, featureChannels: param.output.tensorDim[1]) conv.encode(commandBuffer: commandBuffer, sourceImage: inputImage, destinationImage: outputImage) return } } - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 2) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) + encoder.setBuffer(blankTensor?.buffer, offset: 0, index: 2) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture, groupDepth: type(of: self).isWinoGrad(functionName: functionName) ? 1 : nil) } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 2) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) - encoder.setBuffer(blankTensor?.buffer, offset: 0, index: 2) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture, groupDepth: type(of: self).isWinoGrad(functionName: functionName) ? 1 : nil) - encoder.endEncoding() } - func setupWithMPS(device: MTLDevice, param: ConvParam

) { + func setupWithMPS(device: MTLDevice, param: ConvParam

) throws { let offsetX = (Int(param.dilations[0]) * (param.filter.tensorDim[3] - 1) + 1) / 2 - Int(param.paddings[0]) let offsetY = (Int(param.dilations[1]) * (param.filter.tensorDim[2] - 1) + 1) / 2 - Int(param.paddings[1]) @@ -95,8 +108,8 @@ class ConvKernel: Kernel, Computable { neuronFilter: neuronFilterForMPSLayer(device: device) as? MPSCNNNeuron) desc.strideInPixelsX = Int(param.stride[0]) desc.strideInPixelsY = Int(param.stride[1]) - let _ = param.filter.convert(converter: MPSPointerConverter

.init()) - let dataSource = ConvDataSource.init(inDesc: desc, inWeights: param.filter, inBiasTerms: nil) + let _ = try param.filter.convert(converter: MPSPointerConverter

.init()) + let dataSource = try ConvDataSource.init(inDesc: desc, inWeights: param.filter, inBiasTerms: nil) let conv = MPSCNNConvolution.init(device: device, weights: dataSource) conv.offset = MPSOffset.init(x: offsetX, y: offsetY, z: 0) conv.edgeMode = .zero @@ -104,7 +117,7 @@ class ConvKernel: Kernel, Computable { } } - func setupWithoutMPS(device: MTLDevice, param: ConvParam

) { + func setupWithoutMPS(device: MTLDevice, param: ConvParam

) throws { let offsetX = (Int(param.dilations[0]) * (param.filter.tensorDim[3] - 1) + 1) / 2 - Int(param.paddings[0]) let offsetY = (Int(param.dilations[1]) * (param.filter.tensorDim[2] - 1) + 1) / 2 - Int(param.paddings[1]) let offsetZ = 0.0 @@ -115,12 +128,12 @@ class ConvKernel: Kernel, Computable { metalParam = inMetalParam if type(of: self).isWinoGrad(functionName: functionName) { - let _ = param.filter.convert(converter: WinogradPointerConverter

.init()) + let _ = try param.filter.convert(converter: WinogradPointerConverter

.init()) } let padWhenOneC = !(param.filter.channel == 1 && param.filter.n == param.input.tensorDim[1]) - param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision, padWhenOneC: padWhenOneC) + try param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision, padWhenOneC: padWhenOneC) blankTensor = Tensor

.init(inDim: Dim(inDim: [1, 1, 1, 4]), inLayout: DataLayout.NHWC(), originDimsCount: 4) - blankTensor?.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try blankTensor?.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) } class func kernelFunctionName(param: ConvParam

, useAggressiveOptimization: Bool = false) -> String? { @@ -130,7 +143,7 @@ class ConvKernel: Kernel, Computable { } else if param.filter.channel == 1 && param.filter.n == param.input.tensorDim[1] { if useAggressiveOptimization { let couldUseWinograd = param.filter.width == 3 && param.filter.height == 3 - && param.filter.n <= 16 && param.stride[0] == 1 && param.stride[1] == 1 + && (param.filter.n ?? Int.max) <= 16 && param.stride[0] == 1 && param.stride[1] == 1 && param.dilations[0] == 1 && param.dilations[1] == 1 if couldUseWinograd { return "depthwise_conv_add_relu_3x3_half_winograd" diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvTransposeKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvTransposeKernel.swift index 8d235a2c3c..e5e95d786f 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvTransposeKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ConvTransposeKernel.swift @@ -31,34 +31,36 @@ struct MetalConvTransposeParam { class ConvTransposeKernel: Kernel, Computable{ var metalParam: MetalConvTransposeParam! required init(device: MTLDevice, param: ConvTransposeParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision, convertToNHWC: false, withTranspose: true) + try param.filter.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision, convertToNHWC: false, withTranspose: true) if GlobalConfig.shared.computePrecision == .Float32 { if param.stride == [2, 2] && param.stride == [2, 2] { - super.init(device: device, inFunctionName: "conv_transpose2x2_stride2", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_transpose2x2_stride2", initContext: initContext) } else { - fatalError(" -- conv transpose unsupported yet -- ") + throw PaddleMobileError.makeError(type: .netError, msg: "conv transpose param \(param) unsupported yet") } } else if GlobalConfig.shared.computePrecision == .Float16 { if param.stride == [2, 2] && param.stride == [2, 2] { - super.init(device: device, inFunctionName: "conv_transpose2x2_stride2_half", initContext: initContext) + try super.init(device: device, inFunctionName: "conv_transpose2x2_stride2_half", initContext: initContext) } else { - fatalError(" -- conv transpose unsupported yet -- ") + throw PaddleMobileError.makeError(type: .netError, msg: "conv transpose param \(param) unsupported yet") } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } // let filter: [Float32] = param.filter.buffer.array() // print(" conv transpose filter") // print(filter) - let kernelWidth = UInt16(param.filter.width) - let kernelHeight = UInt16(param.filter.height) + guard let filterWidth = param.filter.width else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") + } + guard let filterHeight = param.filter.height else { + throw PaddleMobileError.makeError(type: .netError, msg: "filter unsupported") + } + let kernelWidth = UInt16(filterWidth) + let kernelHeight = UInt16(filterHeight) let strideX = UInt16(param.stride[0]) let strideY = UInt16(param.stride[1]) @@ -72,16 +74,28 @@ class ConvTransposeKernel: Kernel, Computable{ } func compute(commandBuffer: MTLCommandBuffer, param: ConvTransposeParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.filter.buffer, offset: 0, index: 1) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ElementwiseAddKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ElementwiseAddKernel.swift index c1ee435e3a..15a4e80768 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ElementwiseAddKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ElementwiseAddKernel.swift @@ -28,33 +28,45 @@ class ElementwiseAddKernel: Kernel, Computable { var metalParam: ElementwiseAddMetalParam required init(device: MTLDevice, param: ElementwiseAddParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.inputX.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.inputX.transpose, computePrecision: GlobalConfig.shared.computePrecision) metalParam = ElementwiseAddKernel.metalParamFrom(inputX: param.inputX, inputY: param.inputY, axis: param.axis) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "elementwise_add", initContext: initContext) + try super.init(device: device, inFunctionName: "elementwise_add", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "elementwise_add_half", initContext: initContext) + try super.init(device: device, inFunctionName: "elementwise_add_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: ElementwiseAddParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputXMetalTexture = param.inputX.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "inputX metaltexture is nil") + } + guard let inputYMetalTexture = param.inputY.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "inputY metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputXMetalTexture, index: 0) + encoder.setTexture(inputYMetalTexture, index: 1) + encoder.setTexture(outputMetalTexture, index: 2) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(param.inputX.metalTexture, index: 0) - encoder.setTexture(param.inputY.metalTexture, index: 1) - encoder.setTexture(param.output.metalTexture, index: 2) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } static func metalParamFrom(inputX: Texture, inputY: Texture, axis: Int) -> ElementwiseAddMetalParam { diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ElementwiseAddPreluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ElementwiseAddPreluKernel.swift index 5add30cd45..ca4892d874 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ElementwiseAddPreluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ElementwiseAddPreluKernel.swift @@ -19,13 +19,9 @@ class ElementwiseAddPreluKernel: Kernel, Computable { var metalParam: ElementwiseAddMetalParam required init(device: MTLDevice, param: ElementwiseAddPreluParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.inputX.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.inputX.transpose, computePrecision: GlobalConfig.shared.computePrecision) - param.alpha.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.alpha.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) metalParam = ElementwiseAddMetalParam.init() @@ -51,35 +47,51 @@ class ElementwiseAddPreluKernel: Kernel, Computable { if GlobalConfig.shared.computePrecision == .Float32 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "elementwise_add_channel_float", initContext: initContext) + try super.init(device: device, inFunctionName: "elementwise_add_channel_float", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "elementwise_add_element_float", initContext: initContext) + try super.init(device: device, inFunctionName: "elementwise_add_element_float", initContext: initContext) } else { - super.init(device: device, inFunctionName: "elementwise_add_prelu_float", initContext: initContext) + try super.init(device: device, inFunctionName: "elementwise_add_prelu_float", initContext: initContext) } } else if GlobalConfig.shared.computePrecision == .Float16 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "elementwise_add_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "elementwise_add_channel_half", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "elementwise_add_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "elementwise_add_channel_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "elementwise_add_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "elementwise_add_channel_half", initContext: initContext) } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: ElementwiseAddPreluParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputXMetalTexture = param.inputX.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "inputX metaltexture is nil") + } + guard let inputYMetalTexture = param.inputY.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "inputY metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputXMetalTexture, index: 0) + encoder.setTexture(inputYMetalTexture, index: 1) + encoder.setTexture(outputMetalTexture, index: 2) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + encoder.setBuffer(param.alpha.buffer, offset: 0, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(param.inputX.metalTexture, index: 0) - encoder.setTexture(param.inputY.metalTexture, index: 1) - encoder.setTexture(param.output.metalTexture, index: 2) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.setBuffer(param.alpha.buffer, offset: 0, index: 1) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ExpKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ExpKernel.swift index 69c9bc6ea3..d78956a2c8 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ExpKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ExpKernel.swift @@ -17,27 +17,36 @@ import Foundation class ExpKernel: Kernel, Computable { func compute(commandBuffer: MTLCommandBuffer, param: ExpParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - 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: ExpParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "exp", initContext: initContext) + try super.init(device: device, inFunctionName: "exp", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "exp_half", initContext: initContext) + try super.init(device: device, inFunctionName: "exp_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/FetchKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/FetchKernel.swift index dde2353036..e4fd64afd5 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/FetchKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/FetchKernel.swift @@ -23,38 +23,38 @@ class FetchKernel: Kernel, Computable { param.output.initBuffer(device: device) if GlobalConfig.shared.computePrecision == .Float16 { if param.input.transpose == [0, 2, 3, 1] { - super.init(device: device, inFunctionName: "fetch_half", initContext: initContext) + try super.init(device: device, inFunctionName: "fetch_half", initContext: initContext) } else if param.input.transpose == [0, 1, 2, 3] { switch param.input.tensorDim.cout() { case 1, 2: - super.init(device: device, inFunctionName: "fetch_1or2_half", initContext: initContext) + try super.init(device: device, inFunctionName: "fetch_1or2_half", initContext: initContext) case 4: expectedTranspose = [0, 2, 3, 1] - super.init(device: device, inFunctionName: "fetch_half", initContext: initContext) + try super.init(device: device, inFunctionName: "fetch_half", initContext: initContext) default: - fatalError(" not support ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported tensor dim count") } } else { - fatalError(" not support ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported input transpose") } } else if GlobalConfig.shared.computePrecision == .Float32 { if param.input.transpose == [0, 2, 3, 1] { - super.init(device: device, inFunctionName: "fetch_float", initContext: initContext) + try super.init(device: device, inFunctionName: "fetch_float", initContext: initContext) } else if param.input.transpose == [0, 1, 2, 3] { switch param.input.tensorDim.cout() { case 1, 2: - super.init(device: device, inFunctionName: "fetch_1or2_float", initContext: initContext) + try super.init(device: device, inFunctionName: "fetch_1or2_float", initContext: initContext) case 4: expectedTranspose = [0, 2, 3, 1] - super.init(device: device, inFunctionName: "fetch_float", initContext: initContext) + try super.init(device: device, inFunctionName: "fetch_float", initContext: initContext) default: - fatalError(" not support ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported tensor dim count") } } else { - fatalError(" not support ") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported input transpose") } } else { - fatalError(" not support ") + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } self.device = device self.initContext = initContext @@ -67,16 +67,26 @@ class FetchKernel: Kernel, Computable { if let device = device, let initContext = initContext, let transposedInput = encodeTransposeInput(input: param.input, toTranspose: expectedTranspose, commandBuffer: commandBuffer, device: device, initContext: initContext) { input = transposedInput } else { - print("input transpose failed in slice kernel") + throw PaddleMobileError.makeError(type: .predictError, msg: "input transpose failed in slice kernel") } } } - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setBuffer(param.output.resultBuffer!, offset: 0, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: inputMetalTexture) } - encoder.setTexture(input.metalTexture, index: 0) - encoder.setBuffer(param.output.resultBuffer!, offset: 0, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.input.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/FlattenKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/FlattenKernel.swift index ec2b22709e..ba6c059421 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/FlattenKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/FlattenKernel.swift @@ -28,11 +28,7 @@ class FlattenKernel: Kernel, Computable { required init(device: MTLDevice, param: FlattenParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) var id: [Int32] = [1, 1, 1, 1] for i in 0..: Kernel, Computable { ) let irank = param.input.tensorDim.cout() let orank = param.output.tensorDim.cout() - assert(orank == 2) + guard orank == 2 else { + throw PaddleMobileError.makeError(type: .netError, msg: "output tensordim: \(param.output.tensorDim) rank must be 2") + } if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "reshape_\(irank)_2_float", initContext: initContext) + try super.init(device: device, inFunctionName: "reshape_\(irank)_2_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "reshape_\(irank)_2_half", initContext: initContext) + try super.init(device: device, inFunctionName: "reshape_\(irank)_2_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: FlattenParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } @@ -82,11 +91,7 @@ class Flatten2Kernel: Kernel, Computable { required init(device: MTLDevice, param: Flatten2Param

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) var id: [Int32] = [1, 1, 1, 1] for i in 0..: Kernel, Computable { ) let irank = param.input.tensorDim.cout() let orank = param.output.tensorDim.cout() - assert(orank == 2) + guard orank == 2 else { + throw PaddleMobileError.makeError(type: .netError, msg: "output tensordim: \(param.output.tensorDim) rank must be 2") + } if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "reshape_\(irank)_2_float", initContext: initContext) + try super.init(device: device, inFunctionName: "reshape_\(irank)_2_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "reshape_\(irank)_2_half", initContext: initContext) + try super.init(device: device, inFunctionName: "reshape_\(irank)_2_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: Flatten2Param

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/LeakyReluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/LeakyReluKernel.swift index e1c1dc88c4..5558be5b91 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/LeakyReluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/LeakyReluKernel.swift @@ -21,29 +21,38 @@ struct LeakyReluMetalParam { class LeakyReluKernel: Kernel, Computable { var metalParam: LeakyReluMetalParam func compute(commandBuffer: MTLCommandBuffer, param: LeakyReluParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputTexture, index: 0) + encoder.setTexture(outputTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputTexture) } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } required init(device: MTLDevice, param: LeakyReluParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) metalParam = LeakyReluMetalParam(alpha: param.alpha) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "leaky_relu", initContext: initContext) + try super.init(device: device, inFunctionName: "leaky_relu", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "leaky_relu_half", initContext: initContext) + try super.init(device: device, inFunctionName: "leaky_relu_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/MulticlassNMSKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/MulticlassNMSKernel.swift index f9ba7b8e93..7d7b322b0b 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/MulticlassNMSKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/MulticlassNMSKernel.swift @@ -22,34 +22,49 @@ class MulticlassNMSKernel: Kernel, Computable{ param.middleOutput.initBuffer(device: device) param.bboxOutput.initBuffer(device: device) if GlobalConfig.shared.computePrecision == .Float32 { - pipline1 = device.pipeLine(funcName: "nms_fetch_bbox", metalLoadMode: initContext.metalLoadMode, metalLibPath: initContext.metalLibPath) - super.init(device: device, inFunctionName: "nms_fetch_result", initContext: initContext) + pipline1 = try device.pipeLine(funcName: "nms_fetch_bbox", metalLoadMode: initContext.metalLoadMode, metalLibPath: initContext.metalLibPath) + try super.init(device: device, inFunctionName: "nms_fetch_result", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - pipline1 = device.pipeLine(funcName: "nms_fetch_bbox_half", metalLoadMode: initContext.metalLoadMode, metalLibPath: initContext.metalLibPath) - super.init(device: device, inFunctionName: "nms_fetch_result_half", initContext: initContext) + pipline1 = try device.pipeLine(funcName: "nms_fetch_bbox_half", metalLoadMode: initContext.metalLoadMode, metalLibPath: initContext.metalLibPath) + try super.init(device: device, inFunctionName: "nms_fetch_result_half", initContext: initContext) } else { - fatalError( " unsupport precision " ) + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: MulticlassNMSParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") } - - encoder.setTexture(param.scores.metalTexture, index: 0) - encoder.setBuffer(param.middleOutput.resultBuffer!, offset: 0, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.scores.metalTexture) - encoder.endEncoding() - - guard let encoderBox = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let scoresMetalTexture = param.scores.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "scores metaltexture is nil") + } + guard let bboxesMetalTexture = param.bboxes.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "bboxes metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(scoresMetalTexture, index: 0) + encoder.setBuffer(param.middleOutput.resultBuffer!, offset: 0, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: scoresMetalTexture) } - encoderBox.setTexture(param.bboxes.metalTexture, index: 0) - encoderBox.setBuffer(param.bboxOutput.resultBuffer!, offset: 0, index: 0) - encoderBox.dispatch(computePipline: pipline1, outTexture: param.bboxes.metalTexture) - encoderBox.endEncoding() + do { + guard let encoderBox = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoderBox.endEncoding() + } + encoderBox.setTexture(param.bboxes.metalTexture, index: 0) + encoderBox.setBuffer(param.bboxOutput.resultBuffer!, offset: 0, index: 0) + try encoderBox.dispatch(computePipline: pipline1, outTexture: bboxesMetalTexture) + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/NearestInterpKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/NearestInterpKernel.swift index d7ca978576..c23de61413 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/NearestInterpKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/NearestInterpKernel.swift @@ -21,29 +21,38 @@ struct NearestInterpMetalParam { class NearestInterpKernel: Kernel, Computable { var metalParam: NearestInterpMetalParam func compute(commandBuffer: MTLCommandBuffer, param: NearestInterpParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } required init(device: MTLDevice, param: NearestInterpParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) metalParam = NearestInterpMetalParam(scale: param.scale) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "nearest_interp", initContext: initContext) + try super.init(device: device, inFunctionName: "nearest_interp", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "nearest_interp_half", initContext: initContext) + try super.init(device: device, inFunctionName: "nearest_interp_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PoolKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PoolKernel.swift index 2f340f733e..38264902a9 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PoolKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PoolKernel.swift @@ -28,11 +28,7 @@ class PoolKernel: Kernel, Computable{ var metalParam: PoolMetalParam required init(device: MTLDevice, param: PoolParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) var poolType: Int32 switch param.poolType { @@ -41,7 +37,7 @@ class PoolKernel: Kernel, Computable{ case "avg": poolType = 1 default: - fatalError() + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported pool type: \(param.poolType)") } metalParam = PoolMetalParam.init( ksizeX: param.ksize[0], @@ -54,23 +50,35 @@ class PoolKernel: Kernel, Computable{ ) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "pool_float", initContext: initContext) + try super.init(device: device, inFunctionName: "pool_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "pool_half", initContext: initContext) + try super.init(device: device, inFunctionName: "pool_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: PoolParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PreluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PreluKernel.swift index 8184d998e7..80b437768d 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PreluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PreluKernel.swift @@ -14,46 +14,54 @@ import Foundation -class PreluKernel: Kernel, Computable{ +class PreluKernel: Kernel, Computable { required init(device: MTLDevice, param: PreluParam

, initContext: InitContext) throws { - param.alpha.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) + try param.alpha.initBuffer(device: device, precision: GlobalConfig.shared.computePrecision) - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "prelu_channel", initContext: initContext) + try super.init(device: device, inFunctionName: "prelu_channel", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "prelu_element", initContext: initContext) + try super.init(device: device, inFunctionName: "prelu_element", initContext: initContext) } else { - super.init(device: device, inFunctionName: "prelu_other", initContext: initContext) + try super.init(device: device, inFunctionName: "prelu_other", initContext: initContext) } } else if GlobalConfig.shared.computePrecision == .Float16 { if param.mode == "channel" { - super.init(device: device, inFunctionName: "prelu_channel_half", initContext: initContext) + try super.init(device: device, inFunctionName: "prelu_channel_half", initContext: initContext) } else if param.mode == "element" { - super.init(device: device, inFunctionName: "prelu_element_half", initContext: initContext) + try super.init(device: device, inFunctionName: "prelu_element_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "prelu_other_half", initContext: initContext) + try super.init(device: device, inFunctionName: "prelu_other_half", initContext: initContext) } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: PreluParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBuffer(param.alpha.buffer, offset: 0, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBuffer(param.alpha.buffer, offset: 0, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PriorBoxKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PriorBoxKernel.swift index cb191446bb..d7692b74e1 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PriorBoxKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/PriorBoxKernel.swift @@ -39,33 +39,29 @@ class PriorBoxKernel: Kernel, Computable{ param.output.tensorDim = Dim.init(inDim: [1, originDim[0], originDim[1], originDim[2] * originDim[3]]) param.output.padToFourDim = Dim.init(inDim: [1, originDim[0], originDim[1], originDim[2] * originDim[3]]) - do { - try param.output.initTexture(device: device, inTranspose: [0, 1, 2, 3], computePrecision: GlobalConfig.shared.computePrecision) - try param.outputVariances.initTexture(device: device, inTranspose: [2, 0, 1, 3], computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: [0, 1, 2, 3], computePrecision: GlobalConfig.shared.computePrecision) + try param.outputVariances.initTexture(device: device, inTranspose: [2, 0, 1, 3], computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { if param.min_max_aspect_ratios_order { - super.init(device: device, inFunctionName: "prior_box_MinMaxAspectRatiosOrder", initContext: initContext) + try super.init(device: device, inFunctionName: "prior_box_MinMaxAspectRatiosOrder", initContext: initContext) } else { - super.init(device: device, inFunctionName: "prior_box", initContext: initContext) + try super.init(device: device, inFunctionName: "prior_box", initContext: initContext) } } else if GlobalConfig.shared.computePrecision == .Float16 { if param.min_max_aspect_ratios_order { - super.init(device: device, inFunctionName: "prior_box_MinMaxAspectRatiosOrder_half", initContext: initContext) + try super.init(device: device, inFunctionName: "prior_box_MinMaxAspectRatiosOrder_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "prior_box_half", initContext: initContext) + try super.init(device: device, inFunctionName: "prior_box_half", initContext: initContext) } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } guard param.minSizes.count == 1 else { - fatalError(" need implement ") + throw PaddleMobileError.makeError(type: .netError, msg: "param.minSizes.count must equal to 1") } // let n = 1 @@ -110,14 +106,14 @@ class PriorBoxKernel: Kernel, Computable{ if GlobalConfig.shared.computePrecision == .Float16 { let buffer = device.makeBuffer(length: outputAspectRatior.count * MemoryLayout.size) - float32ToFloat16(input: &outputAspectRatior, output:(buffer?.contents())!, count: outputAspectRatior.count) + try float32ToFloat16(input: &outputAspectRatior, output:(buffer?.contents())!, count: outputAspectRatior.count) param.newAspectRatios = buffer } else if GlobalConfig.shared.computePrecision == .Float32 { let buffer = device.makeBuffer(bytes: outputAspectRatior, length: outputAspectRatior.count * MemoryLayout.size, options: []) param.newAspectRatios = buffer } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } let aspectRatiosSize = uint(outputAspectRatior.count) @@ -135,20 +131,32 @@ class PriorBoxKernel: Kernel, Computable{ } func compute(commandBuffer: MTLCommandBuffer, param: PriorBoxParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + guard let outputVariancesMetalTexture = param.outputVariances.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "outputVariances metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setTexture(outputVariancesMetalTexture, index: 2) + encoder.setBuffer(param.newAspectRatios!, offset: 0, index: 0) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 1) + encoder.setBytes(param.variances, length: MemoryLayout.size * param.variances.count, index: 2) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setTexture(param.outputVariances.metalTexture, index: 2) - - encoder.setBuffer(param.newAspectRatios!, offset: 0, index: 0) - - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 1) - - encoder.setBytes(param.variances, length: MemoryLayout.size * param.variances.count, index: 2) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Relu6Kernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Relu6Kernel.swift index 2152147e9f..2900cc834b 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Relu6Kernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Relu6Kernel.swift @@ -21,29 +21,38 @@ struct Relu6MetalParam { class Relu6Kernel: Kernel, Computable{ var metalParam: Relu6MetalParam func compute(commandBuffer: MTLCommandBuffer, param: Relu6Param

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } required init(device: MTLDevice, param: Relu6Param

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) metalParam = Relu6MetalParam(threshold: param.threshold) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "relu6", initContext: initContext) + try super.init(device: device, inFunctionName: "relu6", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "relu6_half", initContext: initContext) + try super.init(device: device, inFunctionName: "relu6_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ReluKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ReluKernel.swift index 1f370db649..7b380b7108 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ReluKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ReluKernel.swift @@ -16,27 +16,36 @@ import Foundation class ReluKernel: Kernel, Computable{ func compute(commandBuffer: MTLCommandBuffer, param: ReluParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - 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: ReluParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "relu", initContext: initContext) + try super.init(device: device, inFunctionName: "relu", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "relu_half", initContext: initContext) + try super.init(device: device, inFunctionName: "relu_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ReshapeKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ReshapeKernel.swift index 03cc4cad3c..5cf4fd515b 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ReshapeKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ReshapeKernel.swift @@ -32,12 +32,7 @@ class ReshapeKernel: Kernel, Computable{ var metalParam: ReshapeMetalParam required init(device: MTLDevice, param: ReshapeParam

, initContext: InitContext) throws { - - do { - try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) var id: [Int32] = [1, 1, 1, 1] for i in 0..: Kernel, Computable{ let irank = param.input.tensorDim.cout() let orank = param.output.tensorDim.cout() if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "reshape_\(irank)_\(orank)_float", initContext: initContext) + try super.init(device: device, inFunctionName: "reshape_\(irank)_\(orank)_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "reshape_\(irank)_\(orank)_half", initContext: initContext) + try super.init(device: device, inFunctionName: "reshape_\(irank)_\(orank)_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } - required init(device: MTLDevice, testParam: ReshapeTestParam, initContext: InitContext) { + required init(device: MTLDevice, testParam: ReshapeTestParam, initContext: InitContext) throws { metalParam = ReshapeMetalParam.init( idim: (0, 0, 0, 0), itrans: (0, 0, 0, 0), odim: (0, 0, 0, 0), otrans: (0, 0, 0, 0) ) - super.init(device: device, inFunctionName: "reshape", initContext: initContext) + try super.init(device: device, inFunctionName: "reshape", initContext: initContext) } func compute(commandBuffer: MTLCommandBuffer, param: ReshapeParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } - - // func test(commandBuffer: MTLCommandBuffer, testParam: ReshapeTestParam) { - // guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - // fatalError() - // } - // encoder.setTexture(testParam.inputTexture, index: 0) - // encoder.setTexture(testParam.outputTexture, index: 1) - // var pm: ReshapeMetalParam = testParam.param - // encoder.setBytes(&pm, length: MemoryLayout.size, index: 0) - // encoder.dispatch(computePipline: pipline, outTexture: testParam.outputTexture) - // encoder.endEncoding() - // } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ResizeBilinearKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ResizeBilinearKernel.swift index 2165c09baa..9f1f560998 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ResizeBilinearKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ResizeBilinearKernel.swift @@ -21,34 +21,42 @@ struct ResizeBilinearMetalParam { class ResizeBilinearKernel: Kernel, Computable{ required init(device: MTLDevice, param: ResizeBilinearParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "resize_bilinear", initContext: initContext) + try super.init(device: device, inFunctionName: "resize_bilinear", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "resize_bilinear_half", initContext: initContext) + try super.init(device: device, inFunctionName: "resize_bilinear_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .defaultError, msg: "not support compute precision \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: ResizeBilinearParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) let ratio_h: Float32 = Float32(param.input.tensorDim.dims[2]) / Float32(param.output.tensorDim.dims[2]) let ratio_w: Float32 = Float32(param.input.tensorDim.dims[3]) / Float32(param.output.tensorDim.dims[3]) var p = ResizeBilinearMetalParam.init(ratio_h: ratio_h, ratio_w: ratio_w) - encoder.setBytes(&p, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&p, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) + } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Scale.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Scale.swift index 36fecd3369..0a4be80989 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Scale.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Scale.swift @@ -17,14 +17,14 @@ import MetalPerformanceShaders public class ScaleKernel: CusomKernel { var lanczos: MPSImageLanczosScale! - public init(device: MTLDevice, shape: Shape, metalLoadMode: MetalLoadMode, metalLibPath: String?) { + public init(device: MTLDevice, shape: Shape, metalLoadMode: MetalLoadMode, metalLibPath: String?) throws { lanczos = MPSImageLanczosScale(device: device) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: nil, outputDim: shape, metalLoadModel: metalLoadMode, metalLibPath: metalLibPath) + try super.init(device: device, inFunctionName: nil, outputDim: shape, metalLoadModel: metalLoadMode, metalLibPath: metalLibPath) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: nil, outputDim: shape, metalLoadModel: metalLoadMode, metalLibPath: metalLibPath) + try super.init(device: device, inFunctionName: nil, outputDim: shape, metalLoadModel: metalLoadMode, metalLibPath: metalLibPath) } else { - fatalError(" unsupport ") + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ScaleOpKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ScaleOpKernel.swift index 483bedcb08..56480c5a39 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ScaleOpKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ScaleOpKernel.swift @@ -22,72 +22,53 @@ struct ScaleMetalParam { class ScaleOpKernel: Kernel, Computable{ var metalParam: ScaleMetalParam - var mpsScaleOp: AnyObject? var inputImage: AnyObject? var outputImage: AnyObject? required init(device: MTLDevice, param: ScaleParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } - - var shouldUseMPS = false - if initContext.useMPS && param.biasAfterScale && param.input.tensorDim.cout() == 4 && param.output.tensorDim.cout() == 4 { - let inputChannel = param.input.tensorDim[1] - let outputChannel = param.output.tensorDim[1] - if (inputChannel > 4) && (outputChannel > 4) { - shouldUseMPS = true - } - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) metalParam = ScaleMetalParam(scale: param.scale, abias: param.bias) if GlobalConfig.shared.computePrecision == .Float32 { if param.biasAfterScale { - super.init(device: device, inFunctionName: "scale_before_bias_float", initContext: initContext) + try super.init(device: device, inFunctionName: "scale_before_bias_float", initContext: initContext) } else { - super.init(device: device, inFunctionName: "scale_after_bias_float", initContext: initContext) + try super.init(device: device, inFunctionName: "scale_after_bias_float", initContext: initContext) } } else if GlobalConfig.shared.computePrecision == .Float16 { if param.biasAfterScale { - super.init(device: device, inFunctionName: "scale_before_bias_half", initContext: initContext) + try super.init(device: device, inFunctionName: "scale_before_bias_half", initContext: initContext) } else { - super.init(device: device, inFunctionName: "scale_after_bias_half", initContext: initContext) + try super.init(device: device, inFunctionName: "scale_after_bias_half", initContext: initContext) } } else { - fatalError() - } - - if #available(iOS 10.0, *), shouldUseMPS { - mpsScaleOp = MPSCNNNeuronLinear(device: device, a: param.scale, b: param.bias) - param.input.useMPS = true - param.output.useMPS = true + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: ScaleParam

) throws { - if #available(iOS 10.0, *), let mpsScaleOp = mpsScaleOp as? MPSCNNNeuronLinear { - if inputImage == nil { - inputImage = MPSImage.init(texture: param.input.metalTexture, featureChannels: param.input.tensorDim[1]) - } - if outputImage == nil { - outputImage = MPSImage.init(texture: param.output.metalTexture, featureChannels: param.output.tensorDim[1]) - } - if let inputImage = inputImage as? MPSImage, let outputImage = outputImage as? MPSImage { - mpsScaleOp.encode(commandBuffer: commandBuffer, sourceImage: inputImage, destinationImage: outputImage) - } - return + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") } - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ShapeKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ShapeKernel.swift index f547a82cb1..fadfc9ea34 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ShapeKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/ShapeKernel.swift @@ -22,7 +22,7 @@ class ShapeKernel: Kernel, Computable{ func compute(commandBuffer: MTLCommandBuffer, param: ShapeParam

) throws { // print("shape compute") // guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - // throw PaddleMobileError.predictError(message: " encode is nil") + // throw PaddleMobileError.predictError(message: " encoder is nil") // } // encoder.setTexture(param.output.metalTexture, index: 0) // encoder.endEncoding() @@ -30,18 +30,14 @@ class ShapeKernel: Kernel, Computable{ required init(device: MTLDevice, param: ShapeParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "shape", initContext: initContext) + try super.init(device: device, inFunctionName: "shape", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "shape_half", initContext: initContext) + try super.init(device: device, inFunctionName: "shape_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SigmoidKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SigmoidKernel.swift index f740cbb42c..3717f9e05d 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SigmoidKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SigmoidKernel.swift @@ -17,27 +17,36 @@ import Foundation class SigmoidKernel: Kernel, Computable { func compute(commandBuffer: MTLCommandBuffer, param: SigmoidParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - 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: SigmoidParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "sigmoid", initContext: initContext) + try super.init(device: device, inFunctionName: "sigmoid", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "sigmoid_half", initContext: initContext) + try super.init(device: device, inFunctionName: "sigmoid_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SliceKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SliceKernel.swift index 2f24172212..b1c8acbefb 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SliceKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SliceKernel.swift @@ -39,26 +39,34 @@ class SliceKernel: Kernel, Computable { if let device = device, let initContext = initContext, let transposedInput = encodeTransposeInput(input: param.input, toTranspose: expectedTranspose, commandBuffer: commandBuffer, device: device, initContext: initContext) { input = transposedInput } else { - print("input transpose failed in slice kernel") + throw PaddleMobileError.makeError(type: .predictError, msg: "input transpose failed in slice kernel") } } - - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } required init(device: MTLDevice, param: SliceParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) var ranges = [[Int16]]() for i in 0..<4 { if let range = param.ranges[i] { @@ -81,11 +89,11 @@ class SliceKernel: Kernel, Computable { metalParam = SliceMetalParam.init(start0: start0, start1: start1, start2: start2, start3: start3, end0: end0, end1: end1, end2: end2, end3: end3, iC: iC, oC: oC) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "slice", initContext: initContext) + try super.init(device: device, inFunctionName: "slice", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "slice_half", initContext: initContext) + try super.init(device: device, inFunctionName: "slice_half", initContext: initContext) } else { - fatalError("unknown computePrecision") + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } self.device = device self.initContext = initContext diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SoftmaxKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SoftmaxKernel.swift index f0d635c0b4..d4978cd1c0 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SoftmaxKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SoftmaxKernel.swift @@ -24,34 +24,43 @@ class SoftmaxKernel: Kernel, Computable{ var metalParam: SoftmaxMetalParam required init(device: MTLDevice, param: SoftmaxParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) metalParam = SoftmaxMetalParam.init( N: Int32(param.input.tensorDim[0]), K: Int32(param.input.tensorDim[1]) ) if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "softmax_float", initContext: initContext) + try super.init(device: device, inFunctionName: "softmax_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "softmax_half", initContext: initContext) + try super.init(device: device, inFunctionName: "softmax_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: SoftmaxParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encoder is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SplitKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SplitKernel.swift index f9e6ff331e..551fda654c 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SplitKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/SplitKernel.swift @@ -25,29 +25,40 @@ struct SplitMetalParam { class SplitKernel: Kernel, Computable{ var smp: SplitMetalParam func compute(commandBuffer: MTLCommandBuffer, param: SplitParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") } - encoder.setTexture(param.input.metalTexture, index: 0) - for i in 0...size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: inputMetalTexture) } - encoder.setBytes(&smp, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.input.metalTexture) - encoder.endEncoding() } required init(device: MTLDevice, param: SplitParam

, initContext: InitContext) throws { // param.output.initTexture(device: device, computePrecision: computePrecision) let num = param.outputList.count let rank = param.input.tensorDim.cout() - assert(num >= 2 && num <= 4) + guard num >= 2 && num <= 4 else { + throw PaddleMobileError.makeError(type: .netError, msg: "param.outputList.count should satisfy num >= 2 && num <= 4") + } for output in param.outputList { - do { - try output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: GlobalConfig.shared.computePrecision) } smp = SplitMetalParam.init() smp.idim = (Int32(param.input.dim[0]), Int32(param.input.dim[1]), Int32(param.input.dim[2]), Int32(param.input.dim[3])) @@ -83,14 +94,14 @@ class SplitKernel: Kernel, Computable{ } } if v == "normal" { - fatalError("split unsupported") + throw PaddleMobileError.makeError(type: .netError, msg: "unsupported split type") } if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "split_\(rank)_\(num)_\(v)_float", initContext: initContext) + try super.init(device: device, inFunctionName: "split_\(rank)_\(num)_\(v)_float", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "split_\(rank)_\(num)_\(v)_half", initContext: initContext) + try super.init(device: device, inFunctionName: "split_\(rank)_\(num)_\(v)_half", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Texture2DTo2DArrayKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Texture2DTo2DArrayKernel.swift index 7c4bc56c98..69b19464a3 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Texture2DTo2DArrayKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/Texture2DTo2DArrayKernel.swift @@ -25,29 +25,31 @@ struct Texture2DTo2DArrayParam { class Texture2DTo2DArrayKernel: Kernel, Computable{ required init(device: MTLDevice, param: FeedParam

, initContext: InitContext) throws { - - do { - try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: GlobalConfig.shared.computePrecision) if GlobalConfig.shared.computePrecision == .Float16 { - super.init(device: device, inFunctionName: "texture2d_to_2d_array_half", initContext: initContext) + try super.init(device: device, inFunctionName: "texture2d_to_2d_array_half", initContext: initContext) } else if GlobalConfig.shared.computePrecision == .Float32 { - super.init(device: device, inFunctionName: "texture2d_to_2d_array", initContext: initContext) + try super.init(device: device, inFunctionName: "texture2d_to_2d_array", initContext: initContext) } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } } func compute(commandBuffer: MTLCommandBuffer, param: FeedParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(param.input.mtlTexture, index: 0) + encoder.setTexture(param.output.metalTexture, index: 1) + try encoder.dispatch(computePipline: tempPipline, outTexture: param.input.mtlTexture) } - encoder.setTexture(param.input.mtlTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.dispatch(computePipline: pipline, outTexture: param.input.mtlTexture) - encoder.endEncoding() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/TransposeKernel.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/TransposeKernel.swift index 53a02b7636..1ce8b6694f 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/TransposeKernel.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Kernels/TransposeKernel.swift @@ -24,11 +24,7 @@ class TransposeKernel: Kernel, Computable { var metalParam: TransposeMetalParam = TransposeMetalParam.init() required init(device: MTLDevice, param: TransposeParam

, initContext: InitContext) throws { - do { - try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) - } catch let error { - throw error - } + try param.output.initTexture(device: device, computePrecision: GlobalConfig.shared.computePrecision) let rank = param.input.tensorDim.cout() var axis: [Int] = [0, 1, 2, 3] @@ -62,24 +58,34 @@ class TransposeKernel: Kernel, Computable { kernelFunc = "transpose_\(rank)_float" } } else { - fatalError() + throw PaddleMobileError.makeError(type: .predictError, msg: "unsupported compute precision: \(GlobalConfig.shared.computePrecision)") } - print("===========>", kernelFunc) - print(metalParam) - super.init(device: device, inFunctionName: kernelFunc, initContext: initContext) + paddleMobileLog("===========> \(kernelFunc)") + paddleMobileLog("\(metalParam)") + try super.init(device: device, inFunctionName: kernelFunc, initContext: initContext) } func compute(commandBuffer: MTLCommandBuffer, param: TransposeParam

) throws { - guard let encoder = commandBuffer.makeComputeCommandEncoder() else { - throw PaddleMobileError.predictError(message: " encode is nil") + guard let tempPipline = pipline else { + throw PaddleMobileError.makeError(type: .predictError, msg: "pipline is nil") + } + guard let inputMetalTexture = param.input.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "input metaltexture is nil") + } + guard let outputMetalTexture = param.output.metalTexture else { + throw PaddleMobileError.makeError(type: .predictError, msg: "output metaltexture is nil") + } + do { + guard let encoder = commandBuffer.makeComputeCommandEncoder() else { + throw PaddleMobileError.makeError(type: .predictError, msg: "encoder is nil") + } + defer { + encoder.endEncoding() + } + encoder.setTexture(inputMetalTexture, index: 0) + encoder.setTexture(outputMetalTexture, index: 1) + encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) + try encoder.dispatch(computePipline: tempPipline, outTexture: outputMetalTexture) } - - encoder.setTexture(param.input.metalTexture, index: 0) - encoder.setTexture(param.output.metalTexture, index: 1) - encoder.setBytes(&metalParam, length: MemoryLayout.size, index: 0) - encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) - encoder.endEncoding() } - - } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/LeakyReluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/LeakyReluOp.swift index c9ffd9fe47..1b15aa8db4 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/LeakyReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/LeakyReluOp.swift @@ -17,13 +17,9 @@ import Foundation class LeakyReluParam: OpParam { required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try LeakyReluParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try LeakyReluParam.outputOut(outputs: opDesc.outputs, from: inScope) - alpha = try LeakyReluParam.getAttr(key: "alpha", attrs: opDesc.attrs) - } catch let error { - throw error - } + input = try LeakyReluParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try LeakyReluParam.outputOut(outputs: opDesc.outputs, from: inScope) + alpha = try LeakyReluParam.getAttr(key: "alpha", attrs: opDesc.attrs) } let input: Texture var output: Texture @@ -38,16 +34,16 @@ class LeakyReluOp: Operator, LeakyReluP } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - 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()) + print(para.output.metalTexture ?? "") + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/MulticlassNMSOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/MulticlassNMSOp.swift index c8dcf4e023..0eba658a40 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/MulticlassNMSOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/MulticlassNMSOp.swift @@ -17,17 +17,13 @@ import Foundation class MulticlassNMSParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, 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) - - middleOutput = FetchHolder.init(inPaddedCapacity: scores.tensorDim.numel(), inDim: scores.tensorDim) - - bboxOutput = FetchHolder.init(inPaddedCapacity: bboxes.tensorDim.numel(), inDim: bboxes.tensorDim) - } catch let error { - throw error - } + 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) + + middleOutput = FetchHolder.init(inPaddedCapacity: scores.tensorDim.numel(), inDim: scores.tensorDim) + + bboxOutput = FetchHolder.init(inPaddedCapacity: bboxes.tensorDim.numel(), inDim: bboxes.tensorDim) } var bboxOutput: FetchHolder var middleOutput: FetchHolder @@ -38,19 +34,15 @@ class MulticlassNMSParam: OpParam { class MulticlassNMSOp: Operator, MulticlassNMSParam

>, Runable, Creator, InferShaperable{ - func inputVariant() -> [String : [MTLBuffer]] { + func inputVariant() -> [String : [MTLBuffer]]? { guard let scoreBuffer = para.middleOutput.resultBuffer, let bboxBuffer = para.middleOutput.resultBuffer else { - fatalError() + return nil } return ["Scores" : [scoreBuffer], "BBoxes" : [bboxBuffer]] } - func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - fatalError("\(error)") - } + func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) throws { + try kernel.compute(commandBuffer: buffer, param: para) } func inferShape() { @@ -64,7 +56,11 @@ class MulticlassNMSOp: Operator, Mu func delogOutput() { print(" nms - output: ") - print(para.bboxes.metalTexture.float32Array().strideArray()) + do { + let output = try para.bboxes.metalTexture?.float32Array().strideArray() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/NearestInterpOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/NearestInterpOp.swift index 48259c7fc1..78b5144596 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/NearestInterpOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/NearestInterpOp.swift @@ -16,24 +16,19 @@ import Foundation class NearestInterpParam: OpParam { required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try NearestInterpParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try NearestInterpParam.outputOut(outputs: opDesc.outputs, from: inScope) - let inputDim = input.tensorDim - let outputDim = output.tensorDim - guard inputDim.cout() == 4 && outputDim.cout() == 4 && inputDim[0] == outputDim[0] && inputDim[1] == outputDim[1] else { - fatalError("nearest interp only support scale along width and height") - } - let scaleX = Float32(outputDim[2]) / Float32(inputDim[2]) - let scaleY = Float32(outputDim[3]) / Float32(inputDim[3]) - guard abs(scaleX - scaleY) <= 0.00001 else { - fatalError("nearest interp only support same scale factor") - } - scale = scaleX - print("ok") - } catch let error { - throw error + input = try NearestInterpParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try NearestInterpParam.outputOut(outputs: opDesc.outputs, from: inScope) + let inputDim = input.tensorDim + let outputDim = output.tensorDim + guard inputDim.cout() == 4 && outputDim.cout() == 4 && inputDim[0] == outputDim[0] && inputDim[1] == outputDim[1] else { + throw PaddleMobileError.makeError(type: .netError, msg: "nearest interp only support scale along width and height") } + let scaleX = Float32(outputDim[2]) / Float32(inputDim[2]) + let scaleY = Float32(outputDim[3]) / Float32(inputDim[3]) + guard abs(scaleX - scaleY) <= 0.00001 else { + throw PaddleMobileError.makeError(type: .netError, msg: "nearest interp only support same scale factor") + } + scale = scaleX } var input: Texture var output: Texture @@ -47,17 +42,11 @@ class NearestInterpOp: Operator, Ne } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - let device = para.output.metalTexture!.device - let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose) - print(outputArray.strideArray()) + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/PoolOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/PoolOp.swift index 8fed29aedd..ed3b57d50e 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/PoolOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/PoolOp.swift @@ -17,20 +17,17 @@ import Foundation class PoolParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try PoolParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try PoolParam.outputOut(outputs: opDesc.outputs, from: inScope) - poolType = try PoolParam.getAttr(key: "pooling_type", attrs: opDesc.attrs) - ksize = try PoolParam.getAttr(key: "ksize", attrs: opDesc.attrs) - stride = try PoolParam.getAttr(key: "strides", attrs: opDesc.attrs) - padding = try PoolParam.getAttr(key: "paddings", attrs: opDesc.attrs) - ceilMode = try PoolParam.getAttr(key: "ceil_mode", attrs: opDesc.attrs) - globalPooling = try PoolParam.getAttr(key: "global_pooling", attrs: opDesc.attrs) - assert(input.transpose == [0, 2, 3, 1]) - } catch let error { - throw error + input = try PoolParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try PoolParam.outputOut(outputs: opDesc.outputs, from: inScope) + poolType = try PoolParam.getAttr(key: "pooling_type", attrs: opDesc.attrs) + ksize = try PoolParam.getAttr(key: "ksize", attrs: opDesc.attrs) + stride = try PoolParam.getAttr(key: "strides", attrs: opDesc.attrs) + padding = try PoolParam.getAttr(key: "paddings", attrs: opDesc.attrs) + ceilMode = try PoolParam.getAttr(key: "ceil_mode", attrs: opDesc.attrs) + globalPooling = try PoolParam.getAttr(key: "global_pooling", attrs: opDesc.attrs) + guard input.transpose == [0, 2, 3, 1] else { + throw PaddleMobileError.makeError(type: .netError, msg: "input transpose must equal to [0, 2, 3, 1]") } - // let buffer = input.metalTexture.buffer.contents().assumingMemoryBound(to: P.self) } let input: Texture var output: Texture @@ -51,16 +48,16 @@ class PoolOp: Operator, PoolParam

>, Runab } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - 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()) + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } // print("pool2d delog") diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/PreluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/PreluOp.swift index 429e82a493..c79038a23e 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/PreluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/PreluOp.swift @@ -17,14 +17,10 @@ import Foundation class PreluParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try PreluParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try PreluParam.outputOut(outputs: opDesc.outputs, from: inScope) - alpha = try PreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) - mode = try PreluParam.getAttr(key: "mode", attrs: opDesc.attrs) - } catch let error { - throw error - } + input = try PreluParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try PreluParam.outputOut(outputs: opDesc.outputs, from: inScope) + alpha = try PreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) + mode = try PreluParam.getAttr(key: "mode", attrs: opDesc.attrs) } let mode: String let alpha: Tensor

@@ -41,22 +37,26 @@ class PreluOp: Operator, PreluParam

>, Ru } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) input: ") - print(para.input.metalTexture.toTensor(dim: (n: para.input.padToFourDim[0], c: para.input.padToFourDim[1], h: para.input.padToFourDim[2], w: para.input.padToFourDim[3])).strideArray()) + do { + let output = try para.input.metalTexture?.toTensor(dim: (n: para.input.padToFourDim[0], c: para.input.padToFourDim[1], h: para.input.padToFourDim[2], w: para.input.padToFourDim[3])).strideArray() ?? [] + print(output) + } catch _ { + } print(" \(type) Alpha: ") let _: Float32? = para.alpha.buffer.logDesc(header: " alpha: ", stridable: false) print(" \(type) output: ") - print(para.output.metalTexture.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray()) + do { + let output = try para.output.metalTexture?.toTensor(dim: (n: para.output.padToFourDim[0], c: para.output.padToFourDim[1], h: para.output.padToFourDim[2], w: para.output.padToFourDim[3])).strideArray() ?? [] + print(output) + } catch _ { + } } // print("softmax delog") diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/PriorBoxOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/PriorBoxOp.swift index 6af9490766..1dee4ad952 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/PriorBoxOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/PriorBoxOp.swift @@ -22,23 +22,19 @@ class PriorBoxParam: OpParam { } catch _ { } - do { - input = try PriorBoxParam.input(inputs: opDesc.inputs, from: inScope) - output = try PriorBoxParam.outputBoxes(outputs: opDesc.outputs, from: inScope) - inputImage = try PriorBoxParam.inputImage(inputs: opDesc.inputs, from: inScope) - outputVariances = try PriorBoxParam.outputVariances(outputs: opDesc.outputs, from: inScope) - minSizes = try PriorBoxParam.getAttr(key: "min_sizes", attrs: opDesc.attrs) - maxSizes = try PriorBoxParam.getAttr(key: "max_sizes", attrs: opDesc.attrs) - aspectRatios = try PriorBoxParam.getAttr(key: "aspect_ratios", attrs: opDesc.attrs) - variances = try PriorBoxParam.getAttr(key: "variances", attrs: opDesc.attrs) - flip = try PriorBoxParam.getAttr(key: "flip", attrs: opDesc.attrs) - clip = try PriorBoxParam.getAttr(key: "clip", attrs: opDesc.attrs) - stepW = try PriorBoxParam.getAttr(key: "step_w", attrs: opDesc.attrs) - stepH = try PriorBoxParam.getAttr(key: "step_h", attrs: opDesc.attrs) - offset = try PriorBoxParam.getAttr(key: "offset", attrs: opDesc.attrs) - } catch let error { - throw error - } + input = try PriorBoxParam.input(inputs: opDesc.inputs, from: inScope) + output = try PriorBoxParam.outputBoxes(outputs: opDesc.outputs, from: inScope) + inputImage = try PriorBoxParam.inputImage(inputs: opDesc.inputs, from: inScope) + outputVariances = try PriorBoxParam.outputVariances(outputs: opDesc.outputs, from: inScope) + minSizes = try PriorBoxParam.getAttr(key: "min_sizes", attrs: opDesc.attrs) + maxSizes = try PriorBoxParam.getAttr(key: "max_sizes", attrs: opDesc.attrs) + aspectRatios = try PriorBoxParam.getAttr(key: "aspect_ratios", attrs: opDesc.attrs) + variances = try PriorBoxParam.getAttr(key: "variances", attrs: opDesc.attrs) + flip = try PriorBoxParam.getAttr(key: "flip", attrs: opDesc.attrs) + clip = try PriorBoxParam.getAttr(key: "clip", attrs: opDesc.attrs) + stepW = try PriorBoxParam.getAttr(key: "step_w", attrs: opDesc.attrs) + stepH = try PriorBoxParam.getAttr(key: "step_h", attrs: opDesc.attrs) + offset = try PriorBoxParam.getAttr(key: "offset", attrs: opDesc.attrs) } var min_max_aspect_ratios_order: Bool = false @@ -67,56 +63,12 @@ class PriorBoxOp: Operator, PriorBoxPara } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { - - print(" \(type) output: ") - // output - // let outputArray = para.output.metalTexture.float32Array() - // print(outputArray.strideArray()) - // let device = para.input.metalTexture!.device - // let boxes:[Float32] = device.texture2tensor(texture: para.output.metalTexture!, dim: para.output.tensorDim.dims, transpose: [2,0,1,3]) - // let variances:[Float32] = device.texture2tensor(texture: para.outputVariances.metalTexture!, dim: para.outputVariances.tensorDim.dims, transpose: [2,0,1,3]) - // print("boxes: ") - // print(boxes.strideArray()) - // print("variances: ") - // print(variances.strideArray()) - // output print(" \(type) output: ") - - let box = para.output.metalTexture.realNHWC(dim: (para.output.dim[0], para.output.dim[1], para.output.dim[2], para.output.dim[3])) - print(" dim: \(para.output.dim)") - print(box.strideArray()) - // print((0.. Float32 in - // return o - // } - // - // print(" output variance: \(outputVarianceArray)") - - // writeToLibrary(fileName: "variance_out", array: outputVarianceArray) - + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/Relu6Op.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/Relu6Op.swift index 0eaeb9b503..41de13bf17 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/Relu6Op.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/Relu6Op.swift @@ -17,13 +17,9 @@ import Foundation class Relu6Param: OpParam { required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try Relu6Param.inputX(inputs: opDesc.inputs, from: inScope) - output = try Relu6Param.outputOut(outputs: opDesc.outputs, from: inScope) - threshold = try Relu6Param.getAttr(key: "threshold", attrs: opDesc.attrs) - } catch let error { - throw error - } + input = try Relu6Param.inputX(inputs: opDesc.inputs, from: inScope) + output = try Relu6Param.outputOut(outputs: opDesc.outputs, from: inScope) + threshold = try Relu6Param.getAttr(key: "threshold", attrs: opDesc.attrs) } let input: Texture var output: Texture @@ -38,17 +34,17 @@ class Relu6Op: Operator, Relu6Param

>, Ru } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - 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()) + print(para.output.metalTexture ?? "") + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ReluOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ReluOp.swift index 8a782f694b..f99392ebcf 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ReluOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ReluOp.swift @@ -18,12 +18,8 @@ import Foundation class ReluParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try ReluParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try ReluParam.outputOut(outputs: opDesc.outputs, from: inScope) - } catch let error { - throw error - } + input = try ReluParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try ReluParam.outputOut(outputs: opDesc.outputs, from: inScope) } let input: Texture var output: Texture @@ -38,20 +34,12 @@ class ReluOp: Operator, ReluParam

>, Runab } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - 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 device = para.output.metalTexture!.device - // let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose) - // print(outputArray.strideArray()) + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ReshapeOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ReshapeOp.swift index 6cb4934f06..3bdece6033 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ReshapeOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ReshapeOp.swift @@ -18,41 +18,37 @@ import Metal class ReshapeParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try ReshapeParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try ReshapeParam.outputOut(outputs: opDesc.outputs, from: inScope) - shape = try ReshapeParam.getAttr(key: "shape", attrs: opDesc.attrs) - - if shape.count > 4 { - if shape[0] == -1 { - shape.removeFirst() - } + input = try ReshapeParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try ReshapeParam.outputOut(outputs: opDesc.outputs, from: inScope) + shape = try ReshapeParam.getAttr(key: "shape", attrs: opDesc.attrs) + + if shape.count > 4 { + if shape[0] == -1 { + shape.removeFirst() } - - var s: [Int] = shape.map { Int($0) } - - var di = -1 - var ml = 1 - for i in 0..= 0 { - s[di] = input.dim.numel() / ml - } - output.tensorDim = Dim.init(inDim: s) - var dim: [Int] = [1, 1, 1, 1] - for i in 0..= 0 { + s[di] = input.dim.numel() / ml + } + output.tensorDim = Dim.init(inDim: s) + var dim: [Int] = [1, 1, 1, 1] + for i in 0..: Operator, ReshapeParam

: OpParam { typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try ResizeBilinearParam.inputX(inputs: opDesc.inputs, from: inScope) - // if (input.transpose != [0, 2, 3, 1]) || (input.tensorDim.cout() != 4) { - // fatalError() - // } - output = try ResizeBilinearParam.outputOut(outputs: opDesc.outputs, from: inScope) - out_h = try ResizeBilinearParam.getAttr(key: "out_h", attrs: opDesc.attrs) - out_w = try ResizeBilinearParam.getAttr(key: "out_w", attrs: opDesc.attrs) - } catch let error { - throw error - } + input = try ResizeBilinearParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try ResizeBilinearParam.outputOut(outputs: opDesc.outputs, from: inScope) + out_h = try ResizeBilinearParam.getAttr(key: "out_h", attrs: opDesc.attrs) + out_w = try ResizeBilinearParam.getAttr(key: "out_w", attrs: opDesc.attrs) } let input: Texture var output: Texture @@ -44,11 +37,7 @@ class ResizeBilinearOp: Operator, } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ScaleOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ScaleOp.swift index 31f8e4550a..66aed28a33 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ScaleOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ScaleOp.swift @@ -16,15 +16,11 @@ import Foundation class ScaleParam: OpParam { required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try ScaleParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try ScaleParam.outputOut(outputs: opDesc.outputs, from: inScope) - scale = try ScaleParam.getAttr(key: "scale", attrs: opDesc.attrs) - bias = try ScaleParam.getAttr(key: "bias", attrs: opDesc.attrs) - biasAfterScale = try ScaleParam.getAttr(key: "bias_after_scale", attrs: opDesc.attrs) - } catch let error { - throw error - } + input = try ScaleParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try ScaleParam.outputOut(outputs: opDesc.outputs, from: inScope) + scale = try ScaleParam.getAttr(key: "scale", attrs: opDesc.attrs) + bias = try ScaleParam.getAttr(key: "bias", attrs: opDesc.attrs) + biasAfterScale = try ScaleParam.getAttr(key: "bias_after_scale", attrs: opDesc.attrs) } let input: Texture @@ -42,16 +38,16 @@ class ScaleOp: Operator, ScaleParam

>, } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - print(para.output.metalTexture) - 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()) + print(para.output.metalTexture ?? "") + do { + let output = try 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() ?? [] + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/ShapeOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/ShapeOp.swift index c3a1d37f52..4d53d18423 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/ShapeOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/ShapeOp.swift @@ -17,12 +17,8 @@ import Foundation class ShapeParam: OpParam { // typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try ShapeParam.input(inputs: opDesc.inputs, from: inScope) - output = try ShapeParam.outputOut(outputs: opDesc.outputs, from: inScope) - } catch let error { - throw error - } + input = try ShapeParam.input(inputs: opDesc.inputs, from: inScope) + output = try ShapeParam.outputOut(outputs: opDesc.outputs, from: inScope) } var output: Texture let input: Texture @@ -37,11 +33,7 @@ class ShapeOp: Operator, ShapeParam

>, Ru } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/SigmoidOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/SigmoidOp.swift index b445dc4354..93bcd0eb06 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/SigmoidOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/SigmoidOp.swift @@ -17,12 +17,8 @@ import Foundation class SigmoidParam: OpParam { required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try SigmoidParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try SigmoidParam.outputOut(outputs: opDesc.outputs, from: inScope) - } catch let error { - throw error - } + input = try SigmoidParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try SigmoidParam.outputOut(outputs: opDesc.outputs, from: inScope) } let input: Texture var output: Texture @@ -36,16 +32,16 @@ class SigmoidOp: Operator, SigmoidParam

: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try SliceParam.input(inputs: opDesc.inputs, from: inScope) - output = try SliceParam.outputOut(outputs: opDesc.outputs, from: inScope) - starts = try SliceParam.getAttr(key: "starts", attrs: opDesc.attrs) - ends = try SliceParam.getAttr(key: "ends", attrs: opDesc.attrs) - for i in 0..: Operator, SliceParam

>, Ru } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print("\(type) output : ") - print(para.output.toTensor().strideArray()) + do { + let output = try para.output.toTensor().strideArray() + print(output) + } catch _ { + } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/SoftmaxOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/SoftmaxOp.swift index cf56f9590c..f5b5b9d8fa 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/SoftmaxOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/SoftmaxOp.swift @@ -18,19 +18,12 @@ import Metal class SoftmaxParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try SoftmaxParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try SoftmaxParam.outputOut(outputs: opDesc.outputs, from: inScope) - - //assert(input.tensorDim.dims.count == 2) - //assert(input.transpose == [0, 1, 2, 3]) - - output.dim = input.dim - output.tensorDim = input.tensorDim - output.padToFourDim = input.padToFourDim - } catch let error { - throw error - } + input = try SoftmaxParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try SoftmaxParam.outputOut(outputs: opDesc.outputs, from: inScope) + + output.dim = input.dim + output.tensorDim = input.tensorDim + output.padToFourDim = input.padToFourDim } let input: Texture var output: Texture @@ -44,11 +37,7 @@ class SoftmaxOp: Operator, SoftmaxParam

: Operator, SoftmaxParam

: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try SplitParam.inputX(inputs: opDesc.inputs, from: inScope) - output = Texture.init(device: input.metalTexture!.device, inDim: input.dim) - axis = try SplitParam.getAttr(key: "axis", attrs: opDesc.attrs) - sections = try SplitParam.getAttr(key: "sections", attrs: opDesc.attrs) - if axis < 0 { - axis = input.tensorDim.cout() + axis - } - guard let outlist = opDesc.outputs["Out"] else { - fatalError() - } - for out in outlist { - guard let variant = inScope[out], let v = variant as? Texture else { - fatalError() - } - outputList.append(v) - sections.append(Int32(v.tensorDim.dims[axis])) + input = try SplitParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try Texture.init(device: input.metalTexture!.device, inDim: input.dim) + axis = try SplitParam.getAttr(key: "axis", attrs: opDesc.attrs) + sections = try SplitParam.getAttr(key: "sections", attrs: opDesc.attrs) + if axis < 0 { + axis = input.tensorDim.cout() + axis + } + guard let outlist = opDesc.outputs["Out"] else { + throw PaddleMobileError.makeError(type: .netError, msg: "split output desc nil") + } + for out in outlist { + guard let variant = inScope[out], let v = variant as? Texture else { + throw PaddleMobileError.makeError(type: .netError, msg: "split output texture nil") } - } catch let error { - throw error + outputList.append(v) + sections.append(Int32(v.tensorDim.dims[axis])) } } @@ -56,20 +52,12 @@ class SplitOp: Operator, SplitParam

>, Ru } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - let device = para.input.metalTexture!.device - for out in para.outputList { - let arr: [Float32] = device.texture2tensor(texture: out.metalTexture, dim: out.tensorDim.dims, transpose: out.transpose) - print(arr.strideArray()) - } + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Operators/TransposeOp.swift b/metal/paddle-mobile/paddle-mobile/Src/Operators/TransposeOp.swift index 458bbef54f..16ee5b4a82 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Operators/TransposeOp.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Operators/TransposeOp.swift @@ -18,13 +18,9 @@ import Metal class TransposeParam: OpParam { //typealias ParamPrecisionType = P required init(opDesc: PMOpDesc, inScope: Scope) throws { - do { - input = try TransposeParam.inputX(inputs: opDesc.inputs, from: inScope) - output = try TransposeParam.outputOut(outputs: opDesc.outputs, from: inScope) - axis = try TransposeParam.getAttr(key: "axis", attrs: opDesc.attrs) - } catch let error { - throw error - } + input = try TransposeParam.inputX(inputs: opDesc.inputs, from: inScope) + output = try TransposeParam.outputOut(outputs: opDesc.outputs, from: inScope) + axis = try TransposeParam.getAttr(key: "axis", attrs: opDesc.attrs) } let input: Texture var output: Texture @@ -40,18 +36,12 @@ class TransposeOp: Operator, TransposeP } func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { - do { - try kernel.compute(commandBuffer: buffer, param: para) - } catch let error { - throw error - } + try kernel.compute(commandBuffer: buffer, param: para) } func delogOutput() { print(" \(type) output: ") - let device = para.output.metalTexture!.device - let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose) - print(outputArray.strideArray()) + para.output.delog() } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Program/Attribute.swift b/metal/paddle-mobile/paddle-mobile/Src/Program/Attribute.swift index cc8afc994d..4888100417 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Program/Attribute.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Program/Attribute.swift @@ -39,7 +39,7 @@ extension NSMutableArray :Attr { } -func attrWithProtoDesc(attrDesc: OpDesc_Attr) -> Attr { +func attrWithProtoDesc(attrDesc: OpDesc_Attr) throws -> Attr { switch attrDesc.type { case .boolean: return attrDesc.b @@ -79,6 +79,6 @@ func attrWithProtoDesc(attrDesc: OpDesc_Attr) -> Attr { case .strings: return attrDesc.stringsArray default: - fatalError(" not support this attr type: \(attrDesc.type)") + throw PaddleMobileError.makeError(type: .netError, msg: "not support this attr type: \(attrDesc.type)") } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Program/MemoryOptimze.swift b/metal/paddle-mobile/paddle-mobile/Src/Program/MemoryOptimze.swift new file mode 100644 index 0000000000..e52e1e44d1 --- /dev/null +++ b/metal/paddle-mobile/paddle-mobile/Src/Program/MemoryOptimze.swift @@ -0,0 +1,197 @@ +/* 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 MemoryManager { + open var program: Program + open var device: MTLDevice + + init(program: Program, device: MTLDevice) { + self.program = program + self.device = device + } + + public func optimizeProgramMemory() { + + } + + public func reallocMemory() { + + } + + public func makeMetalTextures() { + for block in program.programDesc.blocks { + for varDesc in block.vars { + if !varDesc.persistable && varDesc.type == .LodTensor { + let varEle = program.scope.vars[varDesc.name] + if let texture = varEle as? Texture, let desc = texture.textureDesc { + texture.metalTexture = device.makeTexture(descriptor: desc) + } + } + } + } + } +} + +@available(iOS 10.0, *) +class MemoryOptimize: MemoryManager { + private class Node { + var visited = false + var name = "" + var count = 0 + var texture: Texture? + } + private var memoryBuckets: [MemoryBucket] = [] + + override func makeMetalTextures() { + for bucket in memoryBuckets { + bucket.makeMetalTextures() + } + } + + override func optimizeProgramMemory() { + let programDesc = program.programDesc + var createdNodes = [String: Node]() + var nodesArray = [Node]() + let scope = program.scope + func appendNodes(textureDic: [String: [String]], varsDic: [String: PMVarDesc]) { + for dicPair in textureDic { + for varName in dicPair.value { + if let texture = scope[varName] as? Texture { + let targetVar = varsDic[varName] + if targetVar?.persistable == false && targetVar?.type == .LodTensor { + if let node = createdNodes[varName] { + node.count += 1 + nodesArray.append(node) + } else { + let node = Node.init() + node.name = varName + node.count = 1 + node.texture = texture + createdNodes[varName] = node + nodesArray.append(node) + } + } + } + } + } + } + for block in programDesc.blocks { + var varsDic = [String: PMVarDesc]() + for varDesc in block.vars { + varsDic[varDesc.name] = varDesc + } + for op in block.ops { + appendNodes(textureDic: op.inputs, varsDic: varsDic) + appendNodes(textureDic: op.outputs, varsDic: varsDic) + appendNodes(textureDic: op.inputs, varsDic: varsDic) + } + } + var nodeGroups: [[Node]] = [] + for node in nodesArray { + node.count -= 1 + if !node.visited { + node.visited = true + var placed = false + for i in 0.. (heap?.size ?? 0) { + heap?.setPurgeableState(.empty) + heap = makeHeapForSize(size) + } + } + + public func makeMetalTextures() { + guard let tmpHeap = heap else { + return + } + for texture in textures { + if let desc = texture.textureDesc { + let heapMetalTexture = tmpHeap.makeTexture(descriptor: desc) + heapMetalTexture.makeAliasable() + texture.metalTexture = heapMetalTexture + } + } + } + + private func maxSizeForTextures(_ textures: [Texture]) -> Int { + var maxSize = 0 + for texture in textures { + if let desc = texture.textureDesc { + maxSize = max(maxSize, device.heapTextureSizeAndAlign(descriptor: desc).size) + } else { + paddleMobileLog("texturedesc nil for texture: \(texture)", logLevel: .Warning) + } + } + return maxSize + } + + private func makeHeapForSize(_ size: Int) -> MTLHeap? { + let heapDesc = MTLHeapDescriptor() + heapDesc.size = size + heapDesc.storageMode = .shared + return device.makeHeap(descriptor: heapDesc) + } +} + diff --git a/metal/paddle-mobile/paddle-mobile/Src/Program/PMBlockDesc.swift b/metal/paddle-mobile/paddle-mobile/Src/Program/PMBlockDesc.swift index 27ed620c24..dc10221eb5 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Program/PMBlockDesc.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Program/PMBlockDesc.swift @@ -19,7 +19,7 @@ public class PMBlockDesc { let parentIndex: Int public let vars: [PMVarDesc] let ops: [PMOpDesc] - init(block: BlockDesc) { + init(block: BlockDesc) throws { index = Int(block.idx) parentIndex = Int(block.parentIdx) var vars: [PMVarDesc] = [] @@ -30,7 +30,7 @@ public class PMBlockDesc { self.vars = vars var ops: [PMOpDesc] = [] for op in block.opsArray { - ops.append(PMOpDesc.init(protoOpDesc: op as! OpDesc)) + try ops.append(PMOpDesc.init(protoOpDesc: op as! OpDesc)) } self.ops = ops } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Program/PMOpDesc.swift b/metal/paddle-mobile/paddle-mobile/Src/Program/PMOpDesc.swift index f64a2da1f2..d24780ad5b 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Program/PMOpDesc.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Program/PMOpDesc.swift @@ -21,7 +21,7 @@ class PMOpDesc { let unusedOutputs: [String : [String]] var attrs: [String : Attr] = [:] var type: String - init(protoOpDesc: OpDesc) { + init(protoOpDesc: OpDesc) throws { type = protoOpDesc.type let creator = { (vars: [OpDesc_Var], canAdd: (String) -> Bool) -> [String : [String]] in var map: [String : [String]] = [:] @@ -34,7 +34,7 @@ class PMOpDesc { } guard let _ = opInfos[protoOpDesc.type] else { - fatalError() + throw PaddleMobileError.makeError(type: .opError, msg: "unsupported op type \(String(describing: protoOpDesc.type))") } inputs = creator(protoOpDesc.inputsArray as! [OpDesc_Var]) { @@ -55,7 +55,7 @@ class PMOpDesc { for attr in protoOpDesc.attrsArray { if ((attr as! OpDesc_Attr).type != .block) { - attrs[(attr as! OpDesc_Attr).name] = attrWithProtoDesc(attrDesc: attr as! OpDesc_Attr) + attrs[(attr as! OpDesc_Attr).name] = try attrWithProtoDesc(attrDesc: attr as! OpDesc_Attr) } } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Program/PMProgramDesc.swift b/metal/paddle-mobile/paddle-mobile/Src/Program/PMProgramDesc.swift index 79b8875976..c0be8eb983 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Program/PMProgramDesc.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Program/PMProgramDesc.swift @@ -16,9 +16,9 @@ import Foundation public class PMProgramDesc { public var blocks: [PMBlockDesc] = [] - init(protoProgram: ProgramDesc) { + init(protoProgram: ProgramDesc) throws { for block in protoProgram.blocksArray { - self.blocks.append(PMBlockDesc.init(block: block as! BlockDesc)) + try self.blocks.append(PMBlockDesc.init(block: block as! BlockDesc)) } } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Program/PMVarDesc.swift b/metal/paddle-mobile/paddle-mobile/Src/Program/PMVarDesc.swift index e97f448e29..16214088f8 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Program/PMVarDesc.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Program/PMVarDesc.swift @@ -51,7 +51,7 @@ public enum VarTypeType: Int { case .Bool: return 1 default: - throw PaddleMobileError.memoryError(message: "not support \(self) type to get size ") + throw PaddleMobileError.makeError(type: .memoryError, msg: "not support \(self) type to get size") } } } @@ -61,6 +61,11 @@ public class PMVarDesc { public let persistable: Bool public let type: VarTypeType let tensorDesc: TensorDesc? + public var dims: [Int]? { + get { + return tensorDesc?.dims + } + } init(protoVarDesc: VarDesc) { type = VarTypeType.init(rawValue: Int(protoVarDesc.type.type.rawValue)) ?? .ErrorType name = protoVarDesc.name diff --git a/metal/paddle-mobile/paddle-mobile/Src/Program/ProgramOptimize.swift b/metal/paddle-mobile/paddle-mobile/Src/Program/ProgramOptimize.swift index ad7eb82c35..3baa58b465 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Program/ProgramOptimize.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Program/ProgramOptimize.swift @@ -22,7 +22,6 @@ precedencegroup ChainNode { infix operator --> : ChainNode class Node { - var inputs: [Node] = [] var outputs: [Node] = [] var type: String var opDesc: PMOpDesc? @@ -53,7 +52,6 @@ class Node { static func -->(lNode: Node, rNode: Node) -> Node { lNode.outputs.append(rNode) - rNode.inputs.append(lNode) return rNode } @@ -74,22 +72,22 @@ class Node { return beginNode } - func folderWith(fusion: Fusion.Type, removedNodes: inout [Node]) { + func folderWith(fusion: Fusion.Type, removedNodes: inout [Node]) throws { let fusionNode = fusion.fusionNode() let change = fusion.change() let inOutputs = outputs outputs.removeAll() opDesc?.outputs.removeAll() for i in 0.. { ElementwiseAddPreluOp

.self ] - func optimize(originProgramDesc: PMProgramDesc) -> PMProgramDesc { + func optimize(originProgramDesc: PMProgramDesc) -> PMProgramDesc? { guard originProgramDesc.blocks.count == 1 else { - fatalError(" not support yet") + paddleMobileLog("originProgramDesc.blocks.count != 1", logLevel: .FatalError, callStack: Thread.callStackSymbols) + return nil } var mapForNodeChain: [String : Node] = [:] @@ -206,10 +204,11 @@ class ProgramOptimize { let block = originProgramDesc.blocks[0] for opDesc in block.ops { if GlobalConfig.shared.debug { - print(opDesc.type) + paddleMobileLog(opDesc.type) } guard let opInputKeys = opInfos[opDesc.type]?.inputs, let outputKeys = opInfos[opDesc.type]?.outputs else { - fatalError() + paddleMobileLog("op inputs or outputs nil", logLevel: .FatalError, callStack: Thread.callStackSymbols) + return nil } let node = Node.init(inOpDesc: opDesc) @@ -282,7 +281,12 @@ class ProgramOptimize { } var removeNodes: [Node] = [] - node.node.folderWith(fusion: fusion, removedNodes: &removeNodes) + do { + try node.node.folderWith(fusion: fusion, removedNodes: &removeNodes) + } catch _ { + return nil + } + for removeNode in removeNodes { nodes.remove(element: removeNode) } diff --git a/metal/paddle-mobile/paddle-mobile/Src/Program/TensorDesc.swift b/metal/paddle-mobile/paddle-mobile/Src/Program/TensorDesc.swift index 5871fe0451..c5606897ae 100644 --- a/metal/paddle-mobile/paddle-mobile/Src/Program/TensorDesc.swift +++ b/metal/paddle-mobile/paddle-mobile/Src/Program/TensorDesc.swift @@ -19,7 +19,7 @@ class TensorDesc { let originDimsCount: Int let dataType: VarTypeType let dataLayout: DataLayout = DataLayout.NCHW() - var NCHWDim: [Int] { + var NCHWDim: [Int]? { get { if dims.count != 4 { return dims @@ -31,12 +31,13 @@ class TensorDesc { resultDims.swapAt(1, 3) return resultDims } else { - fatalError(" not support other layout") + paddleMobileLog("not support other layout", logLevel: .FatalError, callStack: Thread.callStackSymbols) + return nil } } } - var NHWCDim: [Int] { + var NHWCDim: [Int]? { get { if dims.count != 4 { return dims @@ -48,12 +49,13 @@ class TensorDesc { resultDims.swapAt(1, 3) return resultDims } else { - fatalError(" not support other layout") + paddleMobileLog("not support other layout", logLevel: .FatalError, callStack: Thread.callStackSymbols) + return nil } } } - init(protoTensorDesc: VarType_TensorDesc) { + init?(protoTensorDesc: VarType_TensorDesc) { // dims = protoTensorDesc.dimsArray.map{ Int64($0)! > 0 ? Int64($0) : abs(Int64($0)) } var dimsArray = [Int]() @@ -70,7 +72,8 @@ class TensorDesc { let headDims = Int(dimsCount - 4) for i in 0..