diff --git a/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift b/metal/MobileNetDemo/MobileNetDemo/MobileNet.swift index c0814601bb3b3221bc1eac14c16fe0b10ef2a90e..f28c3137c82f99e12b1808cfb439aadd8a1dc32b 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 a0d69c5c0633b68adf82582e1cef6357137645a5..675265b2a43f62902b9fce6df231ca544ca9bce1 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 0000000000000000000000000000000000000000..0bbe4140e07f2295bf0f3d5b065c8963998b1e7d --- /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 0000000000000000000000000000000000000000..b1e7d0c915922b982cf002231827bebe6b3bff4a --- /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 0000000000000000000000000000000000000000..18d981003d68d0546c4804ac2ff47dd97c6e7921 --- /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 0000000000000000000000000000000000000000..99841044fd7a167560db34eb77516e2d211f9834 --- /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 0000000000000000000000000000000000000000..b069c4d949bd7c3e27e2ee83d3326d20140d3416 --- /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 0000000000000000000000000000000000000000..d8db8d65fd79fd541b2b7eba75c7378af3448f9c --- /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 0000000000000000000000000000000000000000..da4a164c918651cdd1e11dca5cc62c333f097601 --- /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 0000000000000000000000000000000000000000..bfa36129419f8bd7ad73581cb9f07b8c6eec3fcf --- /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 0000000000000000000000000000000000000000..27f03617d8e36b37ba3a92b0a164d18f8ccd78fe --- /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 0000000000000000000000000000000000000000..23664ef8684d1d02afcfa3a323f1a4d3246ccfab --- /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 0000000000000000000000000000000000000000..d8d4c554aeda2b5700203fc13b2384f29b795b76 --- /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 0000000000000000000000000000000000000000..303cb41b773b18f3ed8d30db81be4add37e94731 --- /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 b3a6d8a9df3a8f5af9d3c6ab9c3169ff658a422e..49d0396fd311b8a38dcb4a9ff786e7e7b3ff5053 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 8af436d7796e445dc60d138927d07d7187db6bf6..cf5cb75a168049b366cb4f5edd078286f4adc35a 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 b248e53bac56ba2018b029406486a29bb52e224f..cd356f8f4783c3da1b795f5a1a8065e347cc55b2 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 608cd3180b0dedabafecb72baf98bf289163de20..6fe27cf7d1260bbc41fbd7b108b6a6759f935c2b 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 7412b41466a128ebc53a317ffbed266f528fbefb..aeafc0f1479ea7d5877d8a20e68f3ee480a92f85 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 38d20557d2a51dd7b9943296b5fc13dc382ebba5..58081a40bf57e2007343663d27ae440cb774480e 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 76feb0ecd07cd3b7d5405e32d674f695a629aa06..3bcf793e7452ef00e0db33f8a382afc5b4fe2821 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 2d80f9b0a2d6d8f8caee49cd3b5677ae277da0e9..193e5ed61369cf3e684677ddbf70c969408ad0f2 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 aa6b43e9bfb9a10e2b9b7f598c63684b643cddc5..deab4de33b428906b46cf62727767c4e955f15b5 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 9a42ba4810be070af94b1b1a5112245f705e3b8c..882af60f79eba279dab66145e015e3189d91d0e3 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 decb9509a613710232de9a006e5289662fe2cae5..cf2f2b00e2144b463b9d1bab80291097630d1494 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 64786d0a45fde417021fc468e5526076ca760753..f5ed25c861ce23d3cc9ef3002963fbfb322bc600 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 a966086c8e74923439e88f109f29a75c8a2131fb..01aa244c90bbd0b9b6220644eaec8265e7b21cdb 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 48f3e953318ebe13a83817097b7c2f0cbb3d4b1f..8e28fa861e82f1a555375d0680d62ff185f18b90 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 e7e88dd00d8c9c7c1ded358767056106c9ebf9fb..9809aae9f3ef5ec27244a0c6a16d06eab3e148a1 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 bac3f3ed916847ecd6b1645c4f77c7119631bb03..cd20db37de5d248b2855fb7c6703228552163ba3 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 77b67bf16ca248c2e3d9bac525c5ee8d64d67255..0867e1b6c5bfd5c7fa25a1c18a28677796361153 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 8ddcf5f555be0856f318659bacbe17d0a9fcd8f4..83f84baa45be54f6b9e4cddb3bf1adddc70a5783 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 15707dcd56454616c8d8463ce26fd7f3c628e0b4..aece17600086eca2d36aad31872867881d8331c2 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 b993850434b46b8b5e6e86a348946fc80ddcd339..871e458539b5f1062c30310691d9f9122a14d438 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 0000000000000000000000000000000000000000..62588a9b53b46125a55941f533dcb70f21835ab7 --- /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 4fc1974c66c1be0ee78b3fcc820944e5ecc01f77..4aa8fac6081480873c5059c6a085e175a737378c 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 37a847b7501ee93c2a9296957725a15594d8801f..b3009cac30e33d189fce6748967f5fd00824fcd1 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 a89dfa3b869b1becc624756ccad853a77afb8bfb..1a033df0920e94471ec27e15e3d7ca0fe2a8edce 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 7e53ea8d1cdd211fa377acb0438b17697685a78b..7cbb22b58d5ce814defc9f7022e4e9c4d10f57aa 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 51703c3e6fd07d6031bda497cf04e79dfc9aa1fe..a2cb5be3bc563467ee7e801e63e23b9b3b373ce6 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 0ca6325922b4d1da2b3e1772503616482f6831d4..f829cd333206b006cffb9cfd9797616574384711 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 6cf8d741a9ad9eda0684b56c58258e50d4d0a683..5813a3c2ebf25bcdd7656c7c11203923caa36c87 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 f22a0026d3a941942feffe5781958727f4f76601..ff97b4122a3429d8fa2ea104da439c302f09fae3 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 dd08da27ace558fad3405067b67002343f2c55a9..3ad1f332cc99b220076bfb56db56dd154fa9aedb 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 03cbeb8187377bd4974d2d6c6d95a693c07b41c0..30e332d739cd0bbbc87a8ad1ea1a4f44d28c3919 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 72be568a672b8294adee736932a76198ad10d058..1acdee3dd6103bd26422486ae5bf267ddde37d1e 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 adbad35b4755f0c093a8f9c49f4c879a91265f8e..9493636edd8d08f5ca1354d0bb4ced420b84e4c5 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 ba1084afab9340b113d6b1695c7227ed2efd6623..25221538e9f48aae3094404b6308e4a4c8cd41a2 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 469644129231d8299589c70e8eb10c3d93690dda..6ec4ba1f22d87cfde6e69d46a8510621eec6c0fc 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 57269354a11a8006b34eacb17b560f587d8c259f..2d19772f374e13a6037741d941fcc530b202ebdc 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 49e146b688e626e87d6641e6271e20b6109cc98e..b29467082263730ab95a5f341c5d4094eacc232e 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 dd3f50c5d41685d043e07c522879f79cff08b76a..b7ce696c953c010904671836d5df276a3f2851bc 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 73a278e3c72460398c2aa17f39d67a7b7a37338d..385ee39ff5b850f54fda503b2d7ebb4518c7551c 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 bcf0ba994ca48b6af18533f36718c1d458239e8e..7d726a598941ad6c5473bed4adb61462fd5a06d7 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 5022d312050cad119982cc409a0a0a0f1b3b0d0c..a15b5079fcaaffe451e02aca9d552b7e3e0d73e3 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 e9a5a395aed840d37e29ea1dec16b34085d80624..2f3db885040a76546f89d80726b3381660d13bfb 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 951e572a88bfad80ab9e3edbef02c2ca47fb99a1..16f2b2ceaabc2919314d252eb1b19e49948918d7 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 2282fdbb179d93378893934d937661652c5fdc43..2bde861feb5981300847cbe6257a97d9ff90ed7d 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 975ef16287596815b518b87cbfbdba0ed8462c51..21988570ba29dae2fb120bf0c5ca18830f0e2288 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 d133918203270a7a4dce7e92c6019726d54c67c5..aa627d34a8bdaf33e6b1f5edff8f2aa42b710b60 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 646a08f1511ed2bb7b9752896e49431a24568833..9c920e6da37ce3d318147a868c636aa6a6f1875f 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 66d9bfd22e1568bf3d77b549b276a66a2d69f347..9aeb8949cf77afefbea163426b73285d2f7c92e2 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 7313837c1293fe864e60a5b4cb699025c706f567..509cdbaaa5da46bf7ad5888f04e6865801d0d361 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 a10e1939dff66192658c1709787aaa0c65875169..cc2d730fd49e505cd6cd43376cf6aace51c3b027 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 eefffd817a16f3edd21f7d2d70ed9a1face2c713..79dfd6f754a376b6ea39dce3f8e0d288d11b4b6e 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 6c6f9261627e778212b1007cb00a679266894fbd..d3fba8df2699292c141f0acce2cf9495646884e4 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 4b742f94d5c33b8e8d7a003691c5e6e9776c4394..28b78cfe1c5ae64a8e2430cddb18d556d357ffac 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 d70caca5f4301d17d44b01fd9bcad44142eb9b50..c5ff740bb00a568f27b53bac1f4f1756d4fa5cad 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 19dc193ac458336cc80fc2eca0f05c5b873efe5d..8255790ac1eace20b9d04d43105cd39b6b1deced 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 8d235a2c3c3409a11a437ed437492a09a470537c..e5e95d786f6994a332b81d28ce2d144e301b2928 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 c1ee435e3a1809a21449a03ecc37d9e3395a3286..15a4e80768ab432520652c205d8fe54028d61fc5 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 5add30cd45e6e028e9784f2bbc0cfc480893cb49..ca4892d874cac8daaabb864d73c53f880b8ed2f1 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 69c9bc6ea395a252a0c00581f9b0224799badda6..d78956a2c86b0fdda0caa2e08844b7f5b19b62c8 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 dde23530361d4507849e83c907c6a600ba227b28..e4fd64afd5df2eeabadf97b3f8da60590d0451e5 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 ec2b22709e700d3a8461f8d221bd4b988a3953a3..ba6c0594212ef22208b50ad0ad8de2e215acda7f 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 e1c1dc88c4cec31cb75979dacb1da0c6d4b4d05f..5558be5b91c19827c9c8171555d47ea04252f905 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 f9ba7b8e9332a2cc04d9c184941c7e090f65a4cb..7d7b322b0b28515c5b75e5c11e91b8781eed8169 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 d7ca9785769048c691046fd1d992b041803af3aa..c23de6141346f23467563a9d98909147da32b348 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 2f340f733eb683f64103b7d2f47b7da0f011b688..38264902a98887a4f7a101613329e25c6a43eacf 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 8184d998e7a1eb9f042efcfdbda7341b91e7ded7..80b437768df2937ddfc89029d2bfa85e47dc7462 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 cb191446bbe49204757c7e9858bb2f9f14da568c..d7692b74e1867142f5be4763053d9044360da02c 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 2152147e9fa126992c0a47a3008ec4cb2ef4c753..2900cc834b8f8e04487b90cc8a4fb6095d7bb42b 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 1f370db649840362e86755c9cb7e37ea2f34b15b..7b380b7108433f55ec5d2b58d46a795e00e8a95f 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 03cc4cad3c0926eac1a72582ab3f80f81b7cbc56..5cf4fd515b6b78ac7d2c43f7a48b3cf7d43e53d9 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 2165c09baab1fcaa91ece6db088493622e02ed6e..9f1f560998b1d839161ccf8fbe89a0158c7119a3 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 36fecd3369efd2c58d85a39762e23d5fcd1fb2eb..0a4be80989c9a2762dee44eb327a9808592f1e9c 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 483bedcb0825049035d8d1a3c76cbfa720bbed7e..56480c5a395d8af8bd1b87718f3caa60b04ef280 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 f547a82cb13af0405e5464b2c9a726bdba58cbfe..fadfc9ea342cb1e26e781829584827f89e1a0b83 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 f740cbb42c0860a07ab319349f5b3da9a0e0fbdd..3717f9e05d562f650d368af7ca1abdcd436694bf 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 2f241722126232e6048007b7f18005ba29e3ac4b..b1c8acbefb7abbff23c31e5687bf24d75966e0f4 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 f0d635c0b4a7574df245325800db0af8e2ec9ea1..d4978cd1c0a7e39f167df2f6d143d194a46d516b 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 f9e6ff331e7018e1f15a70b695c9a1c8a78dad08..551fda654c1d55cb5120ceb7690716f402f0a508 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 7c4bc56c98daedf8bdbe24808b0a6d3068906304..69b19464a380c4fcde735a1bf48f4090c0c332d2 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 53a02b76361f1e28293a98441302af230a23e73b..1ce8b6694f34dc8339844e4e230690323ada661e 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 c9ffd9fe478eeec0fbfd4d0042f71d81e3f9e5c2..1b15aa8db456c1e7807376b617dadcde919baa03 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 c8dcf4e023fdebd7a817bb3b56343f3af8483fdd..0eba658a4076fe409080ea3a6871e7fae02d5eba 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 48259c7fc102ba152c235c7a48c3420a77ba68c9..78b5144596800f3462c2fb093fe907e58a1e50ca 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 8fed29aeddf126ebbe7986a9db4fba0a0d405738..ed3b57d50ebc662fab29909a864821306c261982 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 429e82a49350b42791296330b418c2126b0605e8..c79038a23eba3e272e393510a408ec2648117959 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 6af9490766ba9d2e50ac715ac6a510e207329116..1dee4ad95286b32841d84771d04493e712cc2a58 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 0eaeb9b503c4d307dd22b166f4c7daafd264d0dc..41de13bf176b372d408bec16c3f2b1110072fa1c 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 8a782f694b58cfe99146a8f7df2f1b8c0b5079be..f99392ebcf0713a74c1606facd5cc2aac3322847 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 6cb4934f0646838b01cfcab5d565db432ec69c33..3bdece6033ed0f14d674f6f4ee23abb8583248a2 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 31f8e4550a9e88b51f517e5b15ccfc10c50e2773..66aed28a338ad2b03b9f01fae0ec11282f65cc2c 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 c3a1d37f52286ee21355e308705b07a119c5a1b0..4d53d18423686701d1a89af2a9b239a8141547a5 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 b445dc43549b4d756ad8d6445e9aeab9593a0dca..93bcd0eb06c0df8f3bd9aa9a3d8df791f30c07c4 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 cf56f9590c2ddbfa5b5d190bb71a094239d06311..f5b5b9d8fab3552e6191fba1da5628a16b115419 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 458bbef54fb3136e8b9144e387e8c359873f93d7..16ee5b4a82d5f6a23c2a1b564d99686ea3cf0332 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 cc8afc994d12eb8a1de7f06ba97011b16f56c4b5..48881004179ffeb9e1a55b6d0eb41883656ffb3a 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 0000000000000000000000000000000000000000..e52e1e44d18c290cef8f16ae4405774af56c7074 --- /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 27ed620c24dcbc2f4423debe8b14c4436d0b6dda..dc10221eb5a18c45521af100136191b9d4995cd3 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 f64a2da1f27c60ad50257d86d0c7bae14ab4954b..d24780ad5b1c2af4af3b7816b04553d24466cee2 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 79b8875976dd42eb57ff981441103f001ddb7a6e..c0be8eb9831e7d3c1124fa38b8108155f03fe976 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 e97f448e294c1187a12b4e6bf1139e0425de26b3..16214088f8799eff5f9559dbce04e8ec8ed390bf 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 ad7eb82c35e9f34ba1f4845b12610212f5ce6acb..3baa58b465f51d883f137dd2d04a1d6478fecfb3 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 5871fe045157d78cfb590481d7bc56484ec4bf97..c5606897aea810f14b5d451615ddda39acf9d3c5 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..