提交 48442e3f 编写于 作者: N NazgulLee 提交者: Yanzhan Yang

1.merge workshop; 2.remove scale op mps implementation (#1765)

上级 c0b1f2ef
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
import Foundation import Foundation
import paddle_mobile import paddle_mobile
public class MobileNet: Net{ public class MobileNet: Net {
class MobilenetPreProccess: CusomKernel { class MobilenetPreProccess: CusomKernel {
init(device: MTLDevice) { init(device: MTLDevice) {
let s = Shape.init(inWidth: 224, inHeight: 224, inChannel: 3) let s = Shape.init(inWidth: 224, inHeight: 224, inChannel: 3)
...@@ -31,12 +31,12 @@ public class MobileNet: Net{ ...@@ -31,12 +31,12 @@ public class MobileNet: Net{
contents = string.components(separatedBy: CharacterSet.newlines).filter{$0.count > 10}.map{ contents = string.components(separatedBy: CharacterSet.newlines).filter{$0.count > 10}.map{
String($0[$0.index($0.startIndex, offsetBy: 10)...]) String($0[$0.index($0.startIndex, offsetBy: 10)...])
} }
}else{ } else {
fatalError("no file call \(fileName)") print("no file called \(fileName)")
} }
} }
subscript(index: Int) -> String { subscript(index: Int) -> String {
return contents[index] return index < contents.count ? contents[index] : ""
} }
} }
...@@ -52,15 +52,24 @@ public class MobileNet: Net{ ...@@ -52,15 +52,24 @@ public class MobileNet: Net{
return s.joined(separator: "\n") return s.joined(separator: "\n")
} }
override public init(device: MTLDevice) { override public init(device: MTLDevice) throws {
super.init(device: device) super.init(device: device)
except = 0 except = 0
modelPath = Bundle.main.path(forResource: "mobilenet_model", ofType: nil) ?! "model null" guard let modelPath = Bundle.main.path(forResource: "mobilenet_model", ofType: nil) else {
paramPath = Bundle.main.path(forResource: "mobilenet_params", ofType: nil) ?! "para null" 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) preprocessKernel = MobilenetPreProccess.init(device: device)
inputDim = Dim.init(inDim: [1, 224, 224, 3]) inputDim = Dim.init(inDim: [1, 224, 224, 3])
metalLoadMode = .LoadMetalInCustomMetalLib 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 useMPS = true
} }
} }
......
...@@ -38,7 +38,7 @@ class ViewController: UIViewController { ...@@ -38,7 +38,7 @@ class ViewController: UIViewController {
print(resutText) print(resutText)
self.resultTextView.text = resutText self.resultTextView.text = resutText
} else { } else {
fatalError(" load error ") print("load fail!!!")
} }
} }
...@@ -81,7 +81,8 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll ...@@ -81,7 +81,8 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
picker.dismiss(animated: true){[weak self] in picker.dismiss(animated: true){[weak self] in
guard let sSelf = self, let image = info["UIImagePickerControllerOriginalImage"] as? UIImage else { guard let sSelf = self, let image = info["UIImagePickerControllerOriginalImage"] as? UIImage else {
fatalError("no image") print("no image!!!")
return
} }
sSelf.selectImageView.image = image sSelf.selectImageView.image = image
sSelf.runner.getTexture(image: image.cgImage!, getTexture: { (texture) in sSelf.runner.getTexture(image: image.cgImage!, getTexture: { (texture) in
......
// !$*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 = "<group>"; };
A7138A8622C4AE8D00DE0BD3 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
A7138A8922C4AE8E00DE0BD3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
A7138A8B22C4AE9100DE0BD3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
A7138A8E22C4AE9100DE0BD3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
A7138A9022C4AE9100DE0BD3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A7138A9622C4E36100DE0BD3 /* TestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestViewController.swift; sourceTree = "<group>"; };
A73E3FBA22CA330E00860CFD /* yolo_params_v3_16 */ = {isa = PBXFileReference; lastKnownFileType = file; name = yolo_params_v3_16; path = ../../../../../Documents/paddlemobiletest/yolo_params_v3_16; sourceTree = "<group>"; };
A73E3FBB22CA330E00860CFD /* yolo_model_v3_16 */ = {isa = PBXFileReference; lastKnownFileType = file; name = yolo_model_v3_16; path = ../../../../../Documents/paddlemobiletest/yolo_model_v3_16; sourceTree = "<group>"; };
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 = "<group>"; };
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 = "<group>"; };
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 = "<group>"; };
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 = "<group>"; };
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 = "<group>";
};
467B36527BB8321ECB123A29 /* Pods */ = {
isa = PBXGroup;
children = (
BB4F668F51949D6F7E88641F /* Pods-PaddleMobileTest.debug.xcconfig */,
B9E5E71FB1F45F0539BC30B8 /* Pods-PaddleMobileTest.release.xcconfig */,
);
name = Pods;
path = ../Pods;
sourceTree = "<group>";
};
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 = "<group>";
};
A7138A8222C4AE8D00DE0BD3 /* Products */ = {
isa = PBXGroup;
children = (
A7138A8122C4AE8D00DE0BD3 /* PaddleMobileTest.app */,
);
name = Products;
sourceTree = "<group>";
};
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 = "<group>";
};
/* 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 = "<group>";
};
A7138A8D22C4AE9100DE0BD3 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
A7138A8E22C4AE9100DE0BD3 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* 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 */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:PaddleMobileTest.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A7138A8022C4AE8D00DE0BD3"
BuildableName = "PaddleMobileTest.app"
BlueprintName = "PaddleMobileTest"
ReferencedContainer = "container:PaddleMobileTest.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A7138A8022C4AE8D00DE0BD3"
BuildableName = "PaddleMobileTest.app"
BlueprintName = "PaddleMobileTest"
ReferencedContainer = "container:PaddleMobileTest.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A7138A8022C4AE8D00DE0BD3"
BuildableName = "PaddleMobileTest.app"
BlueprintName = "PaddleMobileTest"
ReferencedContainer = "container:PaddleMobileTest.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A7138A8022C4AE8D00DE0BD3"
BuildableName = "PaddleMobileTest.app"
BlueprintName = "PaddleMobileTest"
ReferencedContainer = "container:PaddleMobileTest.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
//
// 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:.
}
}
{
"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
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ByB-zp-bAl">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Navigation Controller-->
<scene sceneID="nmA-W2-Pg9">
<objects>
<navigationController id="ByB-zp-bAl" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="gOg-IM-7Z2">
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="H9I-lM-OYZ"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ibs-iK-f8W" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1498" y="81"/>
</scene>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="PaddleMobileTest" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
<navigationItem key="navigationItem" id="OTX-aL-mKl"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>need camera</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
//
// 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
}
}
...@@ -32,3 +32,9 @@ target 'paddle-mobile-metallib' do ...@@ -32,3 +32,9 @@ target 'paddle-mobile-metallib' do
project 'paddle-mobile-metallib/paddle-mobile-metallib.xcodeproj' project 'paddle-mobile-metallib/paddle-mobile-metallib.xcodeproj'
end end
target 'PaddleMobileTest' do
project 'PaddleMobileTest/PaddleMobileTest.xcodeproj'
pod 'Protobuf', '~> 3.0.0'
pod 'Alamofire'
end
...@@ -20,12 +20,12 @@ class MultiPredictViewController: UIViewController { ...@@ -20,12 +20,12 @@ class MultiPredictViewController: UIViewController {
var runner2: Runner! var runner2: Runner!
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
let mobileNet = MobileNet_ssd_hand.init(device: MetalHelper.shared.device) let mobileNet = try! MobileNet_ssd_hand.init(device: MetalHelper.shared.device)
let genet = Genet.init(device: MetalHelper.shared.device) let genet = try! Genet.init(device: MetalHelper.shared.device)
runner1 = Runner.init(inNet: mobileNet, commandQueue: MetalHelper.shared.queue) runner1 = try! Runner.init(inNet: mobileNet, commandQueue: MetalHelper.shared.queue)
let queue2 = MetalHelper.shared.device.makeCommandQueue() 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) { @IBAction func predictAct(_ sender: Any) {
......
...@@ -16,32 +16,41 @@ import Foundation ...@@ -16,32 +16,41 @@ import Foundation
import paddle_mobile import paddle_mobile
public class Genet: Net { public class Genet: Net {
@objc public override init(device: MTLDevice) { @objc public override init(device: MTLDevice) throws {
super.init(device: device) try super.init(device: device)
modelPath = Bundle.main.path(forResource: "genet_model", ofType: nil) ?! "model null" guard let modelPath = Bundle.main.path(forResource: "genet_model", ofType: nil) else {
paramPath = Bundle.main.path(forResource: "genet_params", ofType: nil) ?! "para null" throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null")
preprocessKernel = GenetPreProccess.init(device: device) }
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]) inputDim = Dim.init(inDim: [1, 128, 128, 3])
metalLoadMode = .LoadMetalInCustomMetalLib 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) { @objc override public init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) throws {
super.init(device: device, try super.init(device: device,
inParamPointer: inParamPointer, inParamPointer: inParamPointer,
inParamSize: inParamSize, inParamSize: inParamSize,
inModelPointer: inModelPointer, inModelPointer: inModelPointer,
inModelSize: inModelSize) inModelSize: inModelSize)
metalLoadMode = .LoadMetalInCustomMetalLib metalLoadMode = .LoadMetalInCustomMetalLib
metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") 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]) inputDim = Dim.init(inDim: [1, 128, 128, 3])
} }
class GenetPreProccess: CusomKernel { class GenetPreProccess: CusomKernel {
init(device: MTLDevice) { init(device: MTLDevice) throws {
let s = Shape.init(inWidth: 128, inHeight: 128, inChannel: 3) 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)
} }
} }
......
...@@ -18,9 +18,9 @@ import paddle_mobile ...@@ -18,9 +18,9 @@ import paddle_mobile
public class MobileNet: Net{ public class MobileNet: Net{
class MobilenetPreProccess: CusomKernel { class MobilenetPreProccess: CusomKernel {
init(device: MTLDevice) { init(device: MTLDevice) throws {
let s = Shape.init(inWidth: 224, inHeight: 224, inChannel: 3) 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{ ...@@ -32,12 +32,12 @@ public class MobileNet: Net{
contents = string.components(separatedBy: CharacterSet.newlines).filter{$0.count > 10}.map{ contents = string.components(separatedBy: CharacterSet.newlines).filter{$0.count > 10}.map{
String($0[$0.index($0.startIndex, offsetBy: 10)...]) String($0[$0.index($0.startIndex, offsetBy: 10)...])
} }
}else{ } else {
fatalError("no file call \(fileName)") print("no file called \(fileName)")
} }
} }
subscript(index: Int) -> String { subscript(index: Int) -> String {
return contents[index] return index < contents.count ? contents[index] : ""
} }
} }
...@@ -52,17 +52,24 @@ public class MobileNet: Net{ ...@@ -52,17 +52,24 @@ public class MobileNet: Net{
return s.joined(separator: "\n") return s.joined(separator: "\n")
} }
override public init(device: MTLDevice) { override public init(device: MTLDevice) throws {
super.init(device: device) try super.init(device: device)
except = 0 except = 0
modelPath = Bundle.main.path(forResource: "mobilenet_model", ofType: nil) ?! "model null" guard let modelPath = Bundle.main.path(forResource: "mobilenet_model", ofType: nil) else {
paramPath = Bundle.main.path(forResource: "mobilenet_params", ofType: nil) ?! "para null" throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null")
// metalLoadMode = .LoadMetalInCustomMetalLib }
// metalLibPath = Bundle.main.path(forResource: "PaddleMobileMetal", ofType: "metallib") ?! " can't be nil " self.modelPath = modelPath
preprocessKernel = MobilenetPreProccess.init(device: device) 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]) inputDim = Dim.init(inDim: [1, 224, 224, 3])
metalLoadMode = .LoadMetalInCustomMetalLib 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
} }
} }
...@@ -16,18 +16,26 @@ import Foundation ...@@ -16,18 +16,26 @@ import Foundation
import paddle_mobile import paddle_mobile
public class MobileNetCombined: Net { public class MobileNetCombined: Net {
@objc public override init(device: MTLDevice) { @objc public override init(device: MTLDevice) throws {
super.init(device: device) try super.init(device: device)
except = 0 except = 0
modelPath = Bundle.main.path(forResource: "combined_mobilenet_model_16", ofType: nil) ?! "model null" guard let modelPath = Bundle.main.path(forResource: "combined_mobilenet_model_16", ofType: nil) else {
paramPath = Bundle.main.path(forResource: "combined_mobilenet_params_16", ofType: nil) ?! "para null" 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]) inputDim = Dim.init(inDim: [1, 224, 224, 3])
metalLoadMode = .LoadMetalInCustomMetalLib 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 metalLibPath = paddleMobileMetallib
useMPS = true useMPS = true
paramPrecision = .Float16 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") let labels = PreWords.init(fileName: "vision_synset")
...@@ -40,12 +48,12 @@ public class MobileNetCombined: Net { ...@@ -40,12 +48,12 @@ public class MobileNetCombined: Net {
contents = string.components(separatedBy: CharacterSet.newlines).filter{$0.count > 10}.map{ contents = string.components(separatedBy: CharacterSet.newlines).filter{$0.count > 10}.map{
String($0[$0.index($0.startIndex, offsetBy: 10)...]) String($0[$0.index($0.startIndex, offsetBy: 10)...])
} }
}else{ } else {
fatalError("no file call \(fileName)") print("no file called \(fileName)")
} }
} }
subscript(index: Int) -> String { subscript(index: Int) -> String {
return contents[index] return index < contents.count ? contents[index] : ""
} }
} }
......
...@@ -16,32 +16,41 @@ import Foundation ...@@ -16,32 +16,41 @@ import Foundation
import paddle_mobile import paddle_mobile
public class MobileNet_ssd_hand: Net { public class MobileNet_ssd_hand: Net {
@objc public override init(device: MTLDevice) { @objc public override init(device: MTLDevice) throws {
super.init(device: device) try super.init(device: device)
except = 2 except = 2
modelPath = Bundle.main.path(forResource: "ssd_hand_model", ofType: nil) ?! "model null" guard let modelPath = Bundle.main.path(forResource: "ssd_hand_model", ofType: nil) else {
paramPath = Bundle.main.path(forResource: "ssd_hand_params", ofType: nil) ?! "para null" 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 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 {
preprocessKernel = MobilenetssdPreProccess.init(device: device) 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]) inputDim = Dim.init(inDim: [1, 300, 300, 3])
} }
@objc override public init(device: MTLDevice,inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer inModePointer: UnsafeMutableRawPointer, inModelSize: Int) { @objc override public init(device: MTLDevice,inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer inModePointer: UnsafeMutableRawPointer, inModelSize: Int) throws {
super.init(device:device,inParamPointer:inParamPointer,inParamSize:inParamSize,inModelPointer:inModePointer,inModelSize:inModelSize) try super.init(device:device,inParamPointer:inParamPointer,inParamSize:inParamSize,inModelPointer:inModePointer,inModelSize:inModelSize)
except = 2 except = 2
modelPath = "" modelPath = ""
paramPath = "" paramPath = ""
metalLoadMode = .LoadMetalInCustomMetalLib metalLoadMode = .LoadMetalInCustomMetalLib
metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") 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]) inputDim = Dim.init(inDim: [1, 300, 300, 3])
} }
class MobilenetssdPreProccess: CusomKernel { class MobilenetssdPreProccess: CusomKernel {
init(device: MTLDevice) { init(device: MTLDevice) throws {
let s = Shape.init(inWidth: 300, inHeight: 300, inChannel: 3) 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 { ...@@ -50,50 +59,6 @@ public class MobileNet_ssd_hand: Net {
} }
override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] {
return []
// 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<Float32> else {
// fatalError(" need score ")
// }
//
// guard let bboxs = interRes["BBoxes"], bboxs.count > 0, let bbox = bboxs[0] as? Texture<Float32> 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()
} }
} }
...@@ -16,30 +16,39 @@ import Foundation ...@@ -16,30 +16,39 @@ import Foundation
import paddle_mobile import paddle_mobile
public class MobileNet_ssd_AR: Net { public class MobileNet_ssd_AR: Net {
@objc public override init(device: MTLDevice) { @objc public override init(device: MTLDevice) throws {
super.init(device: device) try super.init(device: device)
except = 2 except = 2
modelPath = Bundle.main.path(forResource: "ar_model", ofType: nil) ?! "model null" guard let modelPath = Bundle.main.path(forResource: "ar_model", ofType: nil) else {
paramPath = Bundle.main.path(forResource: "ar_params", ofType: nil) ?! "para null" throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null")
preprocessKernel = MobilenetssdPreProccess.init(device: device) }
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]) inputDim = Dim.init(inDim: [1, 160, 160, 3])
metalLoadMode = .LoadMetalInCustomMetalLib 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) { @objc override public init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize:Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) throws {
super.init(device:device,inParamPointer:inParamPointer,inParamSize:inParamSize,inModelPointer:inModelPointer,inModelSize:inModelSize) try super.init(device:device,inParamPointer:inParamPointer,inParamSize:inParamSize,inModelPointer:inModelPointer,inModelSize:inModelSize)
except = 2 except = 2
preprocessKernel = MobilenetssdPreProccess.init(device: device) preprocessKernel = try MobilenetssdPreProccess.init(device: device)
inputDim = Dim.init(inDim: [1, 160, 160, 3]) inputDim = Dim.init(inDim: [1, 160, 160, 3])
metalLoadMode = .LoadMetalInCustomMetalLib metalLoadMode = .LoadMetalInCustomMetalLib
metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib")
} }
class MobilenetssdPreProccess: CusomKernel { class MobilenetssdPreProccess: CusomKernel {
init(device: MTLDevice) { init(device: MTLDevice) throws {
let s = Shape.init(inWidth: 160, inHeight: 160, inChannel: 3) 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 { ...@@ -48,105 +57,6 @@ public class MobileNet_ssd_AR: Net {
} }
override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { override public func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] {
fatalError() return []
// 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..<score.capacity).map{ score.result[$0] }.strideArray())
//
// print("bbox arr: ")
//
// print((0..<bbox.capacity).map{ bbox.result[$0] }.strideArray())
// let nmsCompute = NMSCompute.init()
// nmsCompute.scoreThredshold = 0.25
// nmsCompute.nmsTopK = 100
// nmsCompute.keepTopK = 100
// nmsCompute.nmsEta = 1.0
// nmsCompute.nmsThreshold = 0.449999988
// nmsCompute.background_label = 0;
// nmsCompute.scoreDim = [NSNumber.init(value: score.dim[0]), NSNumber.init(value: score.dim[1]), NSNumber.init(value: score.dim[2])]
// nmsCompute.bboxDim = [NSNumber.init(value: bbox.dim[0]), NSNumber.init(value: bbox.dim[1]), NSNumber.init(value: bbox.dim[2])]
// guard let result = nmsCompute.compute(withScore: score.result, andBBoxs: bbox.result) else {
// fatalError( " result error " )
// }
// let resultHolder = ResultHolder.init(inResult: result.output, inCapacity: Int(result.outputSize))
// for i in 0..<Int(result.outputSize) {
//
// print("i \(i) : \(result.output[i])")
// }
// print(Date.init().timeIntervalSince(startDate))
// print(resultHolder.result![0])
// return resultHolder
} }
// override func updateProgram(program: Program) {
// for i in [56, 66, 76, 86, 93, 99] {
// let opDesc = program.programDesc.blocks[0].ops[i]
// let output = opDesc.outputs["Out"]!.first!
// let v = program.scope[output]!
// let originTexture = v as! Texture
// originTexture.tensorDim = Dim.init(inDim: [originTexture.tensorDim[1] / 7, originTexture.tensorDim[0] * 7])
//
// originTexture.dim = Dim.init(inDim: [1, 1, originTexture.dim[3] / 7, originTexture.dim[2] * 7])
//
// originTexture.padToFourDim = Dim.init(inDim: [1, 1, originTexture.padToFourDim[3] / 7, originTexture.padToFourDim[2] * 7])
//
// program.scope[output] = originTexture
//
// if i == 99 {
// opDesc.attrs["axis"] = 0
// } else {
// opDesc.attrs["shape"] = originTexture.tensorDim.dims.map { Int32($0) }
// }
// }
//
// for i in [58, 59, 88, 89, 95, 96, 68, 69, 78, 79] {
// let opDesc = program.programDesc.blocks[0].ops[i]
// let output = opDesc.outputs["Out"]!.first!
// let v = program.scope[output]!
//
//
//
// let originTexture = v as! Texture
// originTexture.tensorDim = Dim.init(inDim: [originTexture.tensorDim[1], originTexture.tensorDim[2]])
// opDesc.attrs["shape"] = originTexture.tensorDim.dims.map { Int32($0) }
// }
//
// for i in [60, 101, 90, 97, 70, 80] {
// let opDesc = program.programDesc.blocks[0].ops[i]
// let output = opDesc.outputs["Out"]!.first!
// let v = program.scope[output]!
// let originTexture = v as! Texture
// originTexture.tensorDim = Dim.init(inDim: [originTexture.tensorDim[1], originTexture.tensorDim[2]])
// opDesc.attrs["axis"] = (opDesc.attrs["axis"]! as! Int) - 1
// }
//
// for i in [102] {
// let opDesc = program.programDesc.blocks[0].ops[i]
// for output in opDesc.outputs["Out"]! {
// let v = program.scope[output]!
// let originTexture = v as! Texture
// originTexture.tensorDim = Dim.init(inDim: [originTexture.tensorDim[1], originTexture.tensorDim[2]])
// }
// opDesc.attrs["axis"] = (opDesc.attrs["axis"]! as! Int) - 1
// print(" split axis \(opDesc.attrs["axis"])")
// }
// 99
// }
} }
...@@ -17,17 +17,26 @@ import Foundation ...@@ -17,17 +17,26 @@ import Foundation
import paddle_mobile import paddle_mobile
public class YoloNet: Net { public class YoloNet: Net {
@objc public override init(device: MTLDevice) { @objc public override init(device: MTLDevice) throws {
super.init(device: device) try super.init(device: device)
except = 0 except = 0
modelPath = Bundle.main.path(forResource: "yolo_16_model", ofType: nil) ?! "model null" guard let modelPath = Bundle.main.path(forResource: "yolo_16_model", ofType: nil) else {
paramPath = Bundle.main.path(forResource: "yolo_16_param", ofType: nil) ?! "para null" throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null")
}
self.modelPath = modelPath
guard let paramPath = Bundle.main.path(forResource: "yolo_16_param", ofType: nil) else {
throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "para null")
}
self.paramPath = paramPath
inputDim = Dim.init(inDim: [1, 416, 416, 3]) inputDim = Dim.init(inDim: [1, 416, 416, 3])
metalLoadMode = .LoadMetalInCustomMetalLib 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 useMPS = true
paramPrecision = .Float16 paramPrecision = .Float16
preprocessKernel = ScaleKernel.init(device: device, shape: Shape.init(inWidth: 416, inHeight: 416, inChannel: 3), metalLoadMode: .LoadMetalInCustomMetalLib, metalLibPath: Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib")) preprocessKernel = try ScaleKernel.init(device: device, shape: Shape.init(inWidth: 416, inHeight: 416, inChannel: 3), metalLoadMode: .LoadMetalInCustomMetalLib, metalLibPath: Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib"))
} }
......
...@@ -52,12 +52,15 @@ ...@@ -52,12 +52,15 @@
self = [super init]; self = [super init];
if (self) { if (self) {
Net *net = nil; Net *net = nil;
NSError *error = nil;
if (netType == SuperResolutionNetType) { if (netType == SuperResolutionNetType) {
net = [[SuperResolutionNet alloc] initWithDevice:queue.device inParamPointer:config.paramPointer inParamSize:config.paramSize inModelPointer:config.modelPointer inModelSize:config.modelSize]; net = [[SuperResolutionNet alloc] initWithDevice:queue.device inParamPointer:config.paramPointer inParamSize:config.paramSize inModelPointer:config.modelPointer inModelSize:config.modelSize error:&error];
} else if (netType == MobileNetSSDType) { } else if (netType == MobileNetSSDType) {
net = [[MobileNet_ssd_AR alloc] initWithDevice:queue.device inParamPointer:config.paramPointer inParamSize:config.paramSize inModelPointer:config.modelPointer inModelSize:config.modelSize]; net = [[MobileNet_ssd_AR alloc] initWithDevice:queue.device inParamPointer:config.paramPointer inParamSize:config.paramSize inModelPointer:config.paramPointer inModelSize:config.modelSize error:&error];
}
if (!error && net) {
runner = [[Runner alloc] initInNet:net commandQueue:queue error:&error];
} }
runner = [[Runner alloc] initInNet:net commandQueue:queue];
} }
return self; return self;
} }
......
...@@ -20,8 +20,8 @@ import paddle_mobile ...@@ -20,8 +20,8 @@ import paddle_mobile
return "未实现" return "未实现"
} }
public override init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize: Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) { public override init(device: MTLDevice, inParamPointer: UnsafeMutableRawPointer, inParamSize: Int, inModelPointer: UnsafeMutableRawPointer, inModelSize: Int) throws {
super.init(device: device) try super.init(device: device)
except = 0 except = 0
metalLoadMode = .LoadMetalInCustomMetalLib metalLoadMode = .LoadMetalInCustomMetalLib
metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib") metalLibPath = Bundle.main.path(forResource: "paddle-mobile-metallib", ofType: "metallib")
...@@ -32,15 +32,24 @@ import paddle_mobile ...@@ -32,15 +32,24 @@ import paddle_mobile
self.modelSize = inModelSize self.modelSize = inModelSize
} }
@objc override public init(device: MTLDevice) { @objc override public init(device: MTLDevice) throws {
super.init(device: device) try super.init(device: device)
except = 0 except = 0
modelPath = Bundle.main.path(forResource: "super_model", ofType: nil) ?! "model null" guard let modelPath = Bundle.main.path(forResource: "super_model", ofType: nil) else {
paramPath = Bundle.main.path(forResource: "super_params", ofType: nil) ?! "para null" throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "model null")
}
self.modelPath = modelPath
guard let paramPath = Bundle.main.path(forResource: "super_params", ofType: nil) else {
throw PaddleMobileError.makeError(type: PaddleMobileErrorType.loaderError, msg: "para null")
}
self.paramPath = paramPath
preprocessKernel = nil preprocessKernel = nil
inputDim = Dim.init(inDim: [1, 224, 224, 1]) inputDim = Dim.init(inDim: [1, 224, 224, 1])
metalLoadMode = .LoadMetalInCustomMetalLib 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
} }
override public func updateProgram(program: Program) throws { override public func updateProgram(program: Program) throws {
...@@ -53,13 +62,9 @@ import paddle_mobile ...@@ -53,13 +62,9 @@ import paddle_mobile
if let texture = varEle as? Texture { if let texture = varEle as? Texture {
let newDim = Dim.init(inDim: [texture.dim[0], inputDim[1], inputDim[2], texture.tensorDim[1]]) let newDim = Dim.init(inDim: [texture.dim[0], inputDim[1], inputDim[2], texture.tensorDim[1]])
print(" var desc name " + varDesc.name + " new dim" + "\(newDim)") print(" var desc name " + varDesc.name + " new dim" + "\(newDim)")
do { try texture.updateDims(inTensorDim: Dim.init(inDim: [texture.tensorDim[0], texture.tensorDim[1], inputDim[1], inputDim[2]]), inDim: newDim)
try texture.updateDims(inTensorDim: Dim.init(inDim: [texture.tensorDim[0], texture.tensorDim[1], inputDim[1], inputDim[2]]), inDim: newDim) try texture.initTexture(device: device, inTranspose: [0, 1, 2, 3], computePrecision: GlobalConfig.shared.computePrecision)
try texture.initTexture(device: device, inTranspose: [0, 1, 2, 3], computePrecision: GlobalConfig.shared.computePrecision)
} catch let error {
throw error
}
if let output: FetchHolder = program.scope.output() as? FetchHolder { if let output: FetchHolder = program.scope.output() as? FetchHolder {
output.dim = newDim output.dim = newDim
...@@ -67,7 +72,7 @@ import paddle_mobile ...@@ -67,7 +72,7 @@ import paddle_mobile
output.paddedCapacity = newDim.numel() * 4 output.paddedCapacity = newDim.numel() * 4
output.initBuffer(device: device) output.initBuffer(device: device)
} else { } else {
throw PaddleMobileError.loaderError(message: "scope output nil") throw PaddleMobileError.makeError(type: .loaderError, msg: "scope output nil")
} }
} }
} }
......
...@@ -24,13 +24,13 @@ class FileReader { ...@@ -24,13 +24,13 @@ class FileReader {
let fileSize: Int let fileSize: Int
init(paramPath: String) throws { init(paramPath: String) throws {
guard let tmpFile = fopen(paramPath, "rb") else { 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 file = tmpFile
fseek(file, 0, SEEK_END) fseek(file, 0, SEEK_END)
fileSize = ftell(file) fileSize = ftell(file)
guard fileSize > 0 else { guard fileSize > 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) rewind(file)
} }
...@@ -64,10 +64,10 @@ enum SupportModel: String{ ...@@ -64,10 +64,10 @@ enum SupportModel: String{
} }
let netSupport: [SupportModel : Net] = [ let netSupport: [SupportModel : Net] = [
.super_resolution : SuperResolutionNet.init(device: MetalHelper.shared.device), .super_resolution : try! SuperResolutionNet.init(device: MetalHelper.shared.device),
.yolo : YoloNet.init(device: MetalHelper.shared.device), .yolo : try! YoloNet.init(device: MetalHelper.shared.device),
.mobilenet_combined : MobileNetCombined.init(device: MetalHelper.shared.device), .mobilenet_combined : try! MobileNetCombined.init(device: MetalHelper.shared.device),
.mobilenet : MobileNet.init(device: MetalHelper.shared.device)] .mobilenet : try! MobileNet.init(device: MetalHelper.shared.device)]
class ViewController: UIViewController { class ViewController: UIViewController {
@IBOutlet weak var resultTextView: UITextView! @IBOutlet weak var resultTextView: UITextView!
...@@ -90,7 +90,7 @@ class ViewController: UIViewController { ...@@ -90,7 +90,7 @@ class ViewController: UIViewController {
var threadNum = 1 var threadNum = 1
@IBAction func loadAct(_ sender: Any) { @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 { if platform == .GPU {
// let filePath = Bundle.main.path(forResource: "mingren_input_data", ofType: nil) // let filePath = Bundle.main.path(forResource: "mingren_input_data", ofType: nil)
// let fileReader = try! FileReader.init(paramPath: filePath!) // let fileReader = try! FileReader.init(paramPath: filePath!)
...@@ -109,7 +109,7 @@ class ViewController: UIViewController { ...@@ -109,7 +109,7 @@ class ViewController: UIViewController {
let texture = convertToMTLTexture(imageBuffer: buffer.takeRetainedValue()) let texture = convertToMTLTexture(imageBuffer: buffer.takeRetainedValue())
self.toPredictTexture = texture self.toPredictTexture = texture
} else { } 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) let timeUse = Date.init().timeIntervalSince(beforeDate)
print("get texture time use: \(timeUse)") print("get texture time use: \(timeUse)")
self?.toPredictTexture = texture self?.toPredictTexture = texture
...@@ -117,10 +117,10 @@ class ViewController: UIViewController { ...@@ -117,10 +117,10 @@ class ViewController: UIViewController {
} }
} }
} else { } else {
fatalError( " unsupport " ) print( " unsupport " )
} }
if runner.load() { if runner.load(optimizeProgram: true, optimizeMemory: true) {
print(" load success ! ") print(" load success ! ")
} else { } else {
print(" load error ! ") print(" load error ! ")
...@@ -151,7 +151,8 @@ class ViewController: UIViewController { ...@@ -151,7 +151,8 @@ class ViewController: UIViewController {
for i in 0..<max { for i in 0..<max {
self.runner.predict(texture: inTexture) { [weak self] (success, resultHolder) in self.runner.predict(texture: inTexture) { [weak self] (success, resultHolder) in
guard let sSelf = self else { guard let sSelf = self else {
fatalError() print("runner nil in predict completion")
return
} }
if success, let inResultHolderArr = resultHolder { if success, let inResultHolderArr = resultHolder {
...@@ -205,7 +206,8 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{ ...@@ -205,7 +206,8 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{
} else if pickerView == threadPickerView { } else if pickerView == threadPickerView {
return 1 return 1
} else { } else {
fatalError() print("unsupport picker view")
return 0
} }
} }
...@@ -215,7 +217,8 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{ ...@@ -215,7 +217,8 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{
} else if pickerView == threadPickerView { } else if pickerView == threadPickerView {
return platformSupport.count return platformSupport.count
} else { } else {
fatalError() print("unsupport picker view")
return 0
} }
} }
...@@ -225,7 +228,8 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{ ...@@ -225,7 +228,8 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{
} else if pickerView == threadPickerView { } else if pickerView == threadPickerView {
return platformSupport[row].1 return platformSupport[row].1
} else { } else {
fatalError() print("unsupport picker view")
return ""
} }
} }
...@@ -235,7 +239,7 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{ ...@@ -235,7 +239,7 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{
} else if pickerView == threadPickerView { } else if pickerView == threadPickerView {
platform = platformSupport[row].0 platform = platformSupport[row].0
} else { } else {
fatalError() print("unsupport picker view")
} }
} }
} }
...@@ -244,11 +248,12 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll ...@@ -244,11 +248,12 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
picker.dismiss(animated: true){[weak self] in picker.dismiss(animated: true){[weak self] in
guard let sSelf = self, let image = info["UIImagePickerControllerOriginalImage"] as? UIImage else{ guard let sSelf = self, let image = info["UIImagePickerControllerOriginalImage"] as? UIImage else{
fatalError("no image") print("no image")
return
} }
sSelf.selectImage = image sSelf.selectImage = image
sSelf.selectImageView.image = image sSelf.selectImageView.image = image
sSelf.runner.getTexture(image: image.cgImage!, getTexture: { (texture) in sSelf.runner.getTexture(image: image.cgImage!, getTexture: { (success, texture) in
sSelf.toPredictTexture = texture sSelf.toPredictTexture = texture
}) })
} }
...@@ -257,11 +262,13 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll ...@@ -257,11 +262,13 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll
var bool1 = false var bool1 = false
extension ViewController: VideoCaptureDelegate{ extension ViewController: VideoCaptureDelegate{
func predictTexture(texture: MTLTexture){ func predictTexture(texture: MTLTexture) {
runner.scaleTexture(input: texture) { (scaledTexture) in runner.scaleTexture(input: texture) { (success, scaledTexture) in
self.runner.predict(texture: scaledTexture, completion: { (success, resultHolder) in if success, let scaledTexture = scaledTexture {
resultHolder?.first?.releasePointer() self.runner.predict(texture: scaledTexture, completion: { (success, resultHolder) in
}) resultHolder?.first?.releasePointer()
})
}
} }
} }
......
...@@ -34,3 +34,34 @@ kernel void buffer_to_texture_kernel_half(const device float *input [[buffer(0)] ...@@ -34,3 +34,34 @@ kernel void buffer_to_texture_kernel_half(const device float *input [[buffer(0)]
outTexture.write(half4(y, 0.0f, 0.0f, 0.0f), gid); outTexture.write(half4(y, 0.0f, 0.0f, 0.0f), gid);
} }
kernel void buffer_to_texture_kernel_channel_3(
const device float *input [[buffer(0)]],
texture2d<float, access::write> 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<half, access::write> 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);
}
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
4AA1EAA2214912CD00D0F791 /* FlattenKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */; }; 4AA1EAA2214912CD00D0F791 /* FlattenKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */; };
A73DC749227F1C7A001EB663 /* ScaleOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A73DC748227F1C7A001EB663 /* ScaleOp.swift */; }; A73DC749227F1C7A001EB663 /* ScaleOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A73DC748227F1C7A001EB663 /* ScaleOp.swift */; };
A73DC74B227F1EDE001EB663 /* ScaleOpKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A73DC74A227F1EDE001EB663 /* ScaleOpKernel.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 */; }; A7F26FDA22842EF200365D47 /* Relu6Op.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F26FD922842EF200365D47 /* Relu6Op.swift */; };
A7F26FDC2284301500365D47 /* Relu6Kernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F26FDB2284301500365D47 /* Relu6Kernel.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, ); }; }; C28FE02F21BA68C00054EFAC /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C28FE02C21BA68C00054EFAC /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
...@@ -145,6 +147,8 @@ ...@@ -145,6 +147,8 @@
4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlattenKernel.swift; sourceTree = "<group>"; }; 4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlattenKernel.swift; sourceTree = "<group>"; };
A73DC748227F1C7A001EB663 /* ScaleOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaleOp.swift; sourceTree = "<group>"; }; A73DC748227F1C7A001EB663 /* ScaleOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaleOp.swift; sourceTree = "<group>"; };
A73DC74A227F1EDE001EB663 /* ScaleOpKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaleOpKernel.swift; sourceTree = "<group>"; }; A73DC74A227F1EDE001EB663 /* ScaleOpKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaleOpKernel.swift; sourceTree = "<group>"; };
A744C89622C074AC0084C6E9 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
A744C9B322C206E20084C6E9 /* MemoryOptimze.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryOptimze.swift; sourceTree = "<group>"; };
A7F26FD922842EF200365D47 /* Relu6Op.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Relu6Op.swift; sourceTree = "<group>"; }; A7F26FD922842EF200365D47 /* Relu6Op.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Relu6Op.swift; sourceTree = "<group>"; };
A7F26FDB2284301500365D47 /* Relu6Kernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Relu6Kernel.swift; sourceTree = "<group>"; }; A7F26FDB2284301500365D47 /* Relu6Kernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Relu6Kernel.swift; sourceTree = "<group>"; };
C28FE02C21BA68C00054EFAC /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; C28FE02C21BA68C00054EFAC /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
...@@ -321,6 +325,7 @@ ...@@ -321,6 +325,7 @@
FC039B9D20E11CB20081E9F8 /* Tensor.swift */, FC039B9D20E11CB20081E9F8 /* Tensor.swift */,
FC039B9E20E11CB20081E9F8 /* Dim.swift */, FC039B9E20E11CB20081E9F8 /* Dim.swift */,
FC9D038320E23B01000F735A /* Texture.swift */, FC9D038320E23B01000F735A /* Texture.swift */,
A744C89622C074AC0084C6E9 /* Utils.swift */,
); );
path = Framework; path = Framework;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -386,6 +391,7 @@ ...@@ -386,6 +391,7 @@
FC039BB620E11CC20081E9F8 /* Attribute.swift */, FC039BB620E11CC20081E9F8 /* Attribute.swift */,
FC039BB720E11CC20081E9F8 /* PMBlockDesc.swift */, FC039BB720E11CC20081E9F8 /* PMBlockDesc.swift */,
FC4CB74A20F12C30007C0C6D /* ProgramOptimize.swift */, FC4CB74A20F12C30007C0C6D /* ProgramOptimize.swift */,
A744C9B322C206E20084C6E9 /* MemoryOptimze.swift */,
); );
path = Program; path = Program;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -652,8 +658,10 @@ ...@@ -652,8 +658,10 @@
FC0E2DBE20EE460D009C1FAC /* BatchNormKernel.swift in Sources */, FC0E2DBE20EE460D009C1FAC /* BatchNormKernel.swift in Sources */,
FC039BAB20E11CBC0081E9F8 /* Operator.swift in Sources */, FC039BAB20E11CBC0081E9F8 /* Operator.swift in Sources */,
FCD04E6A20F319EC0007374F /* SoftmaxOp.swift in Sources */, FCD04E6A20F319EC0007374F /* SoftmaxOp.swift in Sources */,
A744C9B422C206E20084C6E9 /* MemoryOptimze.swift in Sources */,
A7F26FDA22842EF200365D47 /* Relu6Op.swift in Sources */, A7F26FDA22842EF200365D47 /* Relu6Op.swift in Sources */,
FCBCCC612122FBDF00D94F7E /* PriorBoxKernel.swift in Sources */, FCBCCC612122FBDF00D94F7E /* PriorBoxKernel.swift in Sources */,
A744C89722C074AC0084C6E9 /* Utils.swift in Sources */,
FCBCCC5F2122FB3B00D94F7E /* PriorBoxOp.swift in Sources */, FCBCCC5F2122FB3B00D94F7E /* PriorBoxOp.swift in Sources */,
FC9D038220E2312E000F735A /* FetchOp.swift in Sources */, FC9D038220E2312E000F735A /* FetchOp.swift in Sources */,
FC039BBD20E11CC20081E9F8 /* Program.swift in Sources */, FC039BBD20E11CC20081E9F8 /* Program.swift in Sources */,
......
...@@ -65,7 +65,7 @@ import Foundation ...@@ -65,7 +65,7 @@ import Foundation
/// 模型精度 /// 模型精度
@objc public var paramPrecision: Precision = .Float32 @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.paramPointer = inParamPointer
self.paramSize = inParamSize self.paramSize = inParamSize
self.modelPointer = inModelPointer self.modelPointer = inModelPointer
...@@ -74,22 +74,23 @@ import Foundation ...@@ -74,22 +74,23 @@ import Foundation
super.init() super.init()
} }
@objc public init(device: MTLDevice) { @objc public init(device: MTLDevice) throws {
self.device = device self.device = device
super.init() super.init()
} }
@objc open func resultStr(res: [ResultHolder]) -> String { @objc open func resultStr(res: [ResultHolder]) -> String {
fatalError() return ""
} }
@objc open func fetchResult(paddleMobileRes: [GPUResultHolder]) -> [ResultHolder] { @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 { 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 ResultHolder.init(inResult: inResPointer, inCapacity: gpuRes.capacity, inDim: gpuRes.dim)
} }
return results ?? []
} }
open func updateProgram(program: Program) throws { open func updateProgram(program: Program) throws {
......
...@@ -35,22 +35,21 @@ import Foundation ...@@ -35,22 +35,21 @@ import Foundation
@objc public class Runner: NSObject { @objc public class Runner: NSObject {
var program: Program? var program: Program?
var executor: Executorable? var executor: Executorable?
var memoryManager: MemoryManager?
var queue: MTLCommandQueue? var queue: MTLCommandQueue?
var textureLoader: MTKTextureLoader? var textureLoader: MTKTextureLoader?
public let net: Net public let net: Net
let device: MTLDevice? let device: MTLDevice?
let numel: Int
private static let loadLock = NSLock() private static let loadLock = NSLock()
private static let clearLock = NSLock() private static let clearLock = NSLock()
/// 初始化函数 /// 初始化函数
/// ///
/// - Parameters: /// - Parameters:
/// - inNet: 传入自定义的网络 /// - inNet: 传入自定义的网络
/// - commandQueue: commandQueue /// - commandQueue: commandQueue
@objc public init(inNet: Net, commandQueue: MTLCommandQueue?) { @objc public init(inNet: Net, commandQueue: MTLCommandQueue?) throws {
guard inNet.inputDim.cout() == 4 else { 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 net = inNet
...@@ -59,7 +58,6 @@ import Foundation ...@@ -59,7 +58,6 @@ import Foundation
if let inDevice = device { if let inDevice = device {
textureLoader = MTKTextureLoader.init(device: inDevice) textureLoader = MTKTextureLoader.init(device: inDevice)
} }
numel = net.inputDim.numel()
} }
/// load 模型, 返回 true 可进行预测,公共方法,保证线程安全 /// load 模型, 返回 true 可进行预测,公共方法,保证线程安全
...@@ -69,25 +67,31 @@ import Foundation ...@@ -69,25 +67,31 @@ import Foundation
Runner.loadLock.lock() Runner.loadLock.lock()
let success = unSafeLoad() let success = unSafeLoad()
Runner.loadLock.unlock() Runner.loadLock.unlock()
if !success {
clear()
}
return success return success
} }
/// load 模型, 返回 true 可进行预测,公共方法,保证线程安全 /// load 模型, 返回 true 可进行预测,公共方法,保证线程安全
/// ///
/// - Returns: load 成功或失败 /// - Returns: load 成功或失败
@objc public func load(optimize: Bool) -> Bool { @objc public func load(optimizeProgram: Bool, optimizeMemory: Bool = true) -> Bool {
Runner.loadLock.lock() Runner.loadLock.lock()
let success = unSafeLoad(optimize: optimize) let success = unSafeLoad(optimizeProgram: optimizeProgram, optimizeMemory: optimizeMemory)
Runner.loadLock.unlock() Runner.loadLock.unlock()
if !success {
clear()
}
return success return success
} }
/// load 模型, 返回 true 可进行预测,不保证线程安全 /// load 模型, 返回 true 可进行预测,不保证线程安全
/// ///
/// - Returns: load 成功或失败 /// - 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 { 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 return false
} }
var loader: Loaderable var loader: Loaderable
...@@ -101,14 +105,14 @@ import Foundation ...@@ -101,14 +105,14 @@ import Foundation
do { do {
if let inParamPointer = net.paramPointer, let inModelPointer = net.modelPointer { if let inParamPointer = net.paramPointer, let inModelPointer = net.modelPointer {
guard net.paramSize > 0 && net.modelSize > 0 else { 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 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 { } 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 { } 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 return false
} }
...@@ -126,8 +130,15 @@ import Foundation ...@@ -126,8 +130,15 @@ import Foundation
} }
try net.updateProgram(program: program!) 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 false
} }
return true return true
...@@ -141,8 +152,17 @@ import Foundation ...@@ -141,8 +152,17 @@ import Foundation
@objc public func predict(texture: MTLTexture, completion: @escaping ( _ success: Bool, _ result: [ResultHolder]?) -> Void) { @objc public func predict(texture: MTLTexture, completion: @escaping ( _ success: Bool, _ result: [ResultHolder]?) -> Void) {
do { do {
guard let executor = self.executor else { guard let executor = self.executor else {
print("executor is empty") paddleMobileLog("executor is empty", logLevel: .FatalError, callStack: Thread.callStackSymbols)
completion(false, nil) 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 return
} }
try executor.predict(input: texture, dim: self.net.inputDim, completionHandle: { [weak self] (success, res) in try executor.predict(input: texture, dim: self.net.inputDim, completionHandle: { [weak self] (success, res) in
...@@ -155,9 +175,10 @@ import Foundation ...@@ -155,9 +175,10 @@ import Foundation
} }
completion(false, nil) completion(false, nil)
}, preProcessKernle: self.net.preprocessKernel, except: self.net.except) }, preProcessKernle: self.net.preprocessKernel, except: self.net.except)
} catch let error { } catch _ {
print(error) DispatchQueue.main.async {
completion(false, nil) completion(false, nil)
}
return return
} }
} }
...@@ -168,6 +189,7 @@ import Foundation ...@@ -168,6 +189,7 @@ import Foundation
executor?.clear() executor?.clear()
executor = nil executor = nil
program = nil program = nil
memoryManager = nil
Runner.clearLock.unlock() Runner.clearLock.unlock()
} }
...@@ -176,9 +198,14 @@ import Foundation ...@@ -176,9 +198,14 @@ import Foundation
/// - Parameters: /// - Parameters:
/// - image: 输入图像 /// - image: 输入图像
/// - getTexture: 获取 texture 回调 /// - getTexture: 获取 texture 回调
@objc public func getTexture(image: CGImage, getTexture: @escaping (MTLTexture) -> Void) { @objc public func getTexture(image: CGImage, getTexture: @escaping (Bool, MTLTexture?) -> Void) {
let texture = try? textureLoader?.newTexture(cgImage: image, options: [:]) ?! " texture loader error" if let textureLoader = textureLoader, let texture = try? textureLoader.newTexture(cgImage: image, options: [:]) {
scaleTexture(input: texture!, complete: getTexture) scaleTexture(input: texture, complete: getTexture)
} else {
DispatchQueue.main.async {
getTexture(false, nil)
}
}
} }
/// 通过 buffer 获取 texture, 内部会使用GPU进行转换操作 /// 通过 buffer 获取 texture, 内部会使用GPU进行转换操作
...@@ -186,27 +213,34 @@ import Foundation ...@@ -186,27 +213,34 @@ import Foundation
/// - Parameters: /// - Parameters:
/// - inBuffer: 输入buffer /// - inBuffer: 输入buffer
/// - getTexture: 结果回调 /// - 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 { 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 { 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 { 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) try bufferToTextureKernel.compute(inputBuffer: inBuffer, commandBuffer: buffer)
} catch { buffer.addCompletedHandler { (buffer) in
fatalError(" bufferToTextureKernel error ") getTexture(true, bufferToTextureKernel.outputTexture)
} }
buffer.commit()
buffer.addCompletedHandler { (buffer) in } catch _ {
getTexture(bufferToTextureKernel.outputTexture) DispatchQueue.main.async {
getTexture(false, nil)
}
return
} }
buffer.commit()
} }
/// 更新输入维度, 针对可变长输入模型 /// 更新输入维度, 针对可变长输入模型
...@@ -215,41 +249,167 @@ import Foundation ...@@ -215,41 +249,167 @@ import Foundation
@objc public func updateInputDim(inDim: Dim) -> Bool { @objc public func updateInputDim(inDim: Dim) -> Bool {
if net.inputDim != inDim { if net.inputDim != inDim {
guard let inProgram = program else { guard let inProgram = program else {
fatalError(" need load first ") paddleMobileLog("need load first", logLevel: .FatalError, callStack: Thread.callStackSymbols)
return false
} }
net.inputDim = inDim net.inputDim = inDim
do { do {
try net.updateProgram(program: inProgram) try net.updateProgram(program: inProgram)
} catch let error { memoryManager?.reallocMemory()
print(error) memoryManager?.makeMetalTextures()
} catch _ {
return false return false
} }
} }
return true 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 { 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 { 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 { 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) try scaleKernel.compute(inputTexuture: input, commandBuffer: buffer)
} catch let error { buffer.addCompletedHandler { (buffer) in
print(error) complete(true, scaleKernel.outputTexture)
fatalError() }
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
} }
} }
...@@ -14,6 +14,16 @@ ...@@ -14,6 +14,16 @@
import Foundation import Foundation
public enum PaddleMobileErrorType {
case loaderError
case netError
case memoryError
case paramError
case opError
case predictError
case defaultError
}
public enum PaddleMobileError: Error{ public enum PaddleMobileError: Error{
case loaderError(message: String) case loaderError(message: String)
case netError(message: String) case netError(message: String)
...@@ -21,4 +31,26 @@ public enum PaddleMobileError: Error{ ...@@ -21,4 +31,26 @@ public enum PaddleMobileError: Error{
case paramError(message: String) case paramError(message: String)
case opError(message: String) case opError(message: String)
case predictError(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<String> = 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)
}
}
} }
...@@ -14,21 +14,6 @@ ...@@ -14,21 +14,6 @@
import Foundation import Foundation
// 自定义 ?! 如果 ?! 前的返回值为一个可选值, 则进行隐式解包, 如果有值则返回这个值, 如果为nil 则fatalError 传入的信息
precedencegroup ExecutedOrFatalError{
associativity: left
higherThan: AssignmentPrecedence
}
infix operator ?!: ExecutedOrFatalError
public func ?!<T>(option: T?, excuteOrError: @autoclosure () -> String) -> T{
if let inOpt = option {
return inOpt
}else{
print(excuteOrError())
fatalError(excuteOrError())
}
}
//Lense //Lense
struct Lense<A, B> { struct Lense<A, B> {
let from: (A) -> B let from: (A) -> B
...@@ -54,22 +39,16 @@ protocol CIntIndex { ...@@ -54,22 +39,16 @@ protocol CIntIndex {
subscript(index: CInt) -> T { get set}; subscript(index: CInt) -> T { get set};
} }
extension Array: CIntIndex{ extension Array: CIntIndex {
typealias T = Element typealias T = Element
subscript(index: CInt) -> T { subscript(index: CInt) -> T {
get{ get {
guard Int64(Int.max) >= Int64(index) else{
fatalError("cint index out of Int range")
}
return self[Int(index)] return self[Int(index)]
} }
set{ set {
guard Int64(Int.max) >= Int64(index) else{
fatalError("cint index out of Int range")
}
self[Int(index)] = newValue self[Int(index)] = newValue
} }
} }
} }
......
...@@ -78,11 +78,20 @@ public class PaddleMobileUnitTest { ...@@ -78,11 +78,20 @@ public class PaddleMobileUnitTest {
odim *= dim[i] odim *= dim[i]
} }
} }
assert(detectPos >= -1) guard detectPos >= -1 else {
print("must satisfy detectPos >= -1")
return
}
if (detectPos == -1) { if (detectPos == -1) {
assert(tensor.count == odim) guard tensor.count == odim else {
print("must satisfy tensor.count == odim")
return
}
} else { } 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 ndim[detectPos] = tensor.count / odim
} }
indentPrintTensor(tensor: tensor, dim: ndim, ix: dim.map { $0 * 0 }, indentLevel: 0) indentPrintTensor(tensor: tensor, dim: ndim, ix: dim.map { $0 * 0 }, indentLevel: 0)
...@@ -175,7 +184,9 @@ public class PaddleMobileUnitTest { ...@@ -175,7 +184,9 @@ public class PaddleMobileUnitTest {
public func testTranspose() { public func testTranspose() {
let buffer = queue.makeCommandBuffer() ?! "buffer is nil" guard let buffer = queue.makeCommandBuffer() else {
return
}
// var input: [Float32] = [] // var input: [Float32] = []
// for i in 0..<72 { // for i in 0..<72 {
// input.append(Float32(i)) // input.append(Float32(i))
...@@ -222,7 +233,9 @@ public class PaddleMobileUnitTest { ...@@ -222,7 +233,9 @@ public class PaddleMobileUnitTest {
} }
public func testConvAddBnRelu() { public func testConvAddBnRelu() {
let buffer = queue.makeCommandBuffer() ?! " buffer is nil " guard let buffer = queue.makeCommandBuffer() else {
return
}
let input: [Float32] = [ let input: [Float32] = [
1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0,
...@@ -299,16 +312,16 @@ public class PaddleMobileUnitTest { ...@@ -299,16 +312,16 @@ public class PaddleMobileUnitTest {
let inputeTexture = device.makeFloatTexture(value: input, textureWidth: 3, textureHeight: 3, arrayLength: 1) let inputeTexture = device.makeFloatTexture(value: input, textureWidth: 3, textureHeight: 3, arrayLength: 1)
//filter //filter
let filterBuffer = device.makeBuffer(value: filter) let filterBuffer = try! device.makeBuffer(value: filter)
// biase // biase
let biaseBuffer = device.makeBuffer(value: biase) let biaseBuffer = try! device.makeBuffer(value: biase)
// new scale // new scale
let newScalueBuffer = device.makeBuffer(value: newScalue) let newScalueBuffer = try! device.makeBuffer(value: newScalue)
// new biase // new biase
let newBiaseBuffer = device.makeBuffer(value: newBiase) let newBiaseBuffer = try! device.makeBuffer(value: newBiase)
//output //output
let outputTexture = device.makeFloatTexture(value: [Float32](), textureWidth: 2, textureHeight: 2, arrayLength: 1) let outputTexture = device.makeFloatTexture(value: [Float32](), textureWidth: 2, textureHeight: 2, arrayLength: 1)
...@@ -332,9 +345,9 @@ public class PaddleMobileUnitTest { ...@@ -332,9 +345,9 @@ public class PaddleMobileUnitTest {
let initContext = InitContext.init() let initContext = InitContext.init()
initContext.metalLoadMode = .LoadMetalInDefaultLib initContext.metalLoadMode = .LoadMetalInDefaultLib
let convAddBnReluKernel = ConvAddBatchNormReluKernel<Float32>.init(device: device, testParam: param, initContext: initContext) let convAddBnReluKernel = try! ConvAddBatchNormReluKernel<Float32>.init(device: device, testParam: param, initContext: initContext)
convAddBnReluKernel.test(commandBuffer: buffer, param: param) try! convAddBnReluKernel.test(commandBuffer: buffer, param: param)
buffer.addCompletedHandler { (buffer) in buffer.addCompletedHandler { (buffer) in
let _: Float32? = inputeTexture.logDesc(header: "input texture", stridable: false) let _: Float32? = inputeTexture.logDesc(header: "input texture", stridable: false)
......
...@@ -14,30 +14,40 @@ ...@@ -14,30 +14,40 @@
import Foundation import Foundation
func writeToLibrary<P: PrecisionProtocol>(fileName: String, array: [P]) { func writeToLibrary<P: PrecisionProtocol>(fileName: String, array: [P]) throws {
let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last ?! " library path get error " guard let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last else {
throw PaddleMobileError.makeError(type: .defaultError, msg: "library path get error")
}
let filePath = libraryPath + "/" + fileName let filePath = libraryPath + "/" + fileName
let fileManager = FileManager.init() let fileManager = FileManager.init()
fileManager.createFile(atPath: filePath, contents: nil, attributes: nil) 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)) let data = Data.init(buffer: UnsafeBufferPointer.init(start: array, count: array.count))
fileHandler.write(data) fileHandler.write(data)
fileHandler.closeFile() fileHandler.closeFile()
} }
public func writeToLibrary<P: PrecisionProtocol>(fileName: String, buffer: UnsafeBufferPointer<P>) { public func writeToLibrary<P: PrecisionProtocol>(fileName: String, buffer: UnsafeBufferPointer<P>) throws {
let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last ?! " library path get error " guard let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last else {
throw PaddleMobileError.makeError(type: .defaultError, msg: "library path get error")
}
let filePath = libraryPath + "/" + fileName let filePath = libraryPath + "/" + fileName
let fileManager = FileManager.init() let fileManager = FileManager.init()
fileManager.createFile(atPath: filePath, contents: nil, attributes: nil) 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) let data = Data.init(buffer: buffer)
fileHandler.write(data) fileHandler.write(data)
fileHandler.closeFile() fileHandler.closeFile()
} }
func createFile(fileName: String) -> String { func createFile(fileName: String) throws -> String {
let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last ?! " library path get error " guard let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last else {
throw PaddleMobileError.makeError(type: .defaultError, msg: "library path get error")
}
let filePath = libraryPath + "/" + fileName let filePath = libraryPath + "/" + fileName
let fileManager = FileManager.init() let fileManager = FileManager.init()
fileManager.createFile(atPath: filePath, contents: nil, attributes: nil) fileManager.createFile(atPath: filePath, contents: nil, attributes: nil)
......
...@@ -24,7 +24,7 @@ public protocol SummableMultipliable: Equatable { ...@@ -24,7 +24,7 @@ public protocol SummableMultipliable: Equatable {
public protocol PrecisionProtocol: SummableMultipliable{ public protocol PrecisionProtocol: SummableMultipliable{
// init(inFloat: Float32) // init(inFloat: Float32)
// init(inFloat16: Float16) // init(inFloat16: Float16)
init<P: PrecisionProtocol>(_ inP: P) init<P: PrecisionProtocol>(_ inP: P) throws
static var bitSize: UInt { get } static var bitSize: UInt { get }
static func initializeValue() -> Self static func initializeValue() -> Self
static var precisionType: Precision { get } static var precisionType: Precision { get }
...@@ -41,36 +41,21 @@ extension Float16: PrecisionProtocol { ...@@ -41,36 +41,21 @@ extension Float16: PrecisionProtocol {
return 0 return 0
} }
public init<P>(_ inP: P) where P : PrecisionProtocol { public init<P>(_ inP: P) throws where P : PrecisionProtocol {
switch P.precisionType { switch P.precisionType {
case .Float32: case .Float32:
fatalError() throw PaddleMobileError.makeError(type: .defaultError, msg: "Float16 can not be initialized from Float32")
case .Float16: case .Float16:
self = inP as! Int16 self = inP as! Int16
default: 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 { public static var bitSize: UInt {
return 16 return 16
} }
// public init(inFloat16: Float16) {
// self = inFloat16
// }
// public init(inFloat: Float32) {
// self = Int16(inFloat)
// }
} }
extension Float32: PrecisionProtocol { extension Float32: PrecisionProtocol {
...@@ -83,56 +68,41 @@ extension Float32: PrecisionProtocol { ...@@ -83,56 +68,41 @@ extension Float32: PrecisionProtocol {
return 0.0 return 0.0
} }
public init<P>(_ inP: P) where P : PrecisionProtocol { public init<P>(_ inP: P) throws where P : PrecisionProtocol {
switch P.precisionType { switch P.precisionType {
case .Float32: case .Float32:
self = inP as! Float32 self = inP as! Float32
case .Float16: case .Float16:
self = Float32.init(Int32.init(inP as! Int16)) self = Float32.init(Int32.init(inP as! Int16))
default: 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 { public static var bitSize: UInt {
return 32 return 32
} }
} }
public func float32ToFloat16(input: UnsafeMutablePointer<Float32>, output: UnsafeMutableRawPointer, count: Int) { public func float32ToFloat16(input: UnsafeMutablePointer<Float32>, output: UnsafeMutableRawPointer, count: Int) throws {
var float32Buffer = vImage_Buffer(data: input, height: 1, width: UInt(count), rowBytes: count * 4) 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) var float16buffer = vImage_Buffer(data: output, height: 1, width: UInt(count), rowBytes: count * 2)
guard vImageConvert_PlanarFtoPlanar16F(&float32Buffer, &float16buffer, 0) == kvImageNoError else { 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<Float16>, count: Int) -> [Float32] { public func float16To32(input: UnsafeMutablePointer<Float16>, count: Int) throws -> [Float32] {
var output = Array<Float>.init(repeating: 0.0, count: count) var output = Array<Float>.init(repeating: 0.0, count: count)
float16to32(input: input, output: &output, count: count) try float16to32(input: input, output: &output, count: count)
return output return output
} }
public func float16to32(input: UnsafeMutablePointer<Float16>, output: UnsafeMutablePointer<Float32>, count: Int) { public func float16to32(input: UnsafeMutablePointer<Float16>, output: UnsafeMutablePointer<Float32>, count: Int) throws {
var bufferFloat16 = vImage_Buffer(data: input, height: 1, width: UInt(count), rowBytes: count * 2) 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) var bufferFloat32 = vImage_Buffer(data: output, height: 1, width: UInt(count), rowBytes: count * 4)
if vImageConvert_Planar16FtoPlanarF(&bufferFloat16, &bufferFloat32, 0) != kvImageNoError { 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 { ...@@ -229,9 +199,9 @@ public class FetchHolder: Variant {
resultBuffer = device.makeBuffer(length: paddedCapacity * 4, options: []) resultBuffer = device.makeBuffer(length: paddedCapacity * 4, options: [])
} }
var result: UnsafeMutablePointer<Float32> { var result: UnsafeMutablePointer<Float32>? {
guard let inResultBuffer = resultBuffer else { guard let inResultBuffer = resultBuffer else {
fatalError() return nil
} }
return inResultBuffer.contents().bindMemory(to: Float32.self, capacity: paddedCapacity) return inResultBuffer.contents().bindMemory(to: Float32.self, capacity: paddedCapacity)
} }
...@@ -240,16 +210,14 @@ public class FetchHolder: Variant { ...@@ -240,16 +210,14 @@ public class FetchHolder: Variant {
extension FetchHolder: CustomStringConvertible, CustomDebugStringConvertible { extension FetchHolder: CustomStringConvertible, CustomDebugStringConvertible {
public var description: String { public var description: String {
fatalError() return "FetchHolder: dim \(dim) capacity \(capacity) paddedCapacity \(paddedCapacity)"
// return "\(result)" // return "\(result)"
} }
public var debugDescription: String { public var debugDescription: String {
fatalError() return "FetchHolder: dim \(dim) capacity \(capacity) paddedCapacity \(paddedCapacity)"
// return "\(result)" // return "\(result)"
} }
} }
......
...@@ -49,7 +49,8 @@ import Foundation ...@@ -49,7 +49,8 @@ import Foundation
dims.swapAt(index1, index2) dims.swapAt(index1, index2)
} }
private override init(){ private override init() {
fatalError() dims = []
super.init()
} }
} }
...@@ -36,7 +36,7 @@ var isTest = false ...@@ -36,7 +36,7 @@ var isTest = false
} }
public override var description: String { public override var description: String {
fatalError() return ""
} }
} }
...@@ -65,12 +65,8 @@ public class Executor<P: PrecisionProtocol>: Executorable{ ...@@ -65,12 +65,8 @@ public class Executor<P: PrecisionProtocol>: Executorable{
//block.ops.count //block.ops.count
for i in 0..<block.ops.count { for i in 0..<block.ops.count {
let opDesc = block.ops[i] let opDesc = block.ops[i]
do { let op = try OpCreator<P>.shared.creat(device: inDevice, opDesc: opDesc, scope: inProgram.scope, initContext: initContext)
let op = try OpCreator<P>.shared.creat(device: inDevice, opDesc: opDesc, scope: inProgram.scope, initContext: initContext) ops.append(op)
ops.append(op)
} catch let error {
throw error
}
} }
} }
} }
...@@ -79,21 +75,17 @@ public class Executor<P: PrecisionProtocol>: Executorable{ ...@@ -79,21 +75,17 @@ public class Executor<P: PrecisionProtocol>: Executorable{
inflightSemaphore.wait() inflightSemaphore.wait()
guard isValid else { guard isValid else {
inflightSemaphore.signal() 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 { guard let buffer = queue.makeCommandBuffer() else {
inflightSemaphore.signal() inflightSemaphore.signal()
throw PaddleMobileError.predictError(message: "CommandBuffer is nil") throw PaddleMobileError.makeError(type: .predictError, msg: "CommandBuffer is nil")
} }
let resInput: MTLTexture let resInput: MTLTexture
if let inPre = preProcessKernle { if let inPre = preProcessKernle {
do { try inPre.compute(inputTexuture: input, commandBuffer: buffer)
try inPre.compute(inputTexuture: input, commandBuffer: buffer) resInput = inPre.outputTexture
resInput = inPre.outputTexture
} catch let error {
throw error
}
} else { } else {
resInput = input resInput = input
} }
...@@ -103,16 +95,12 @@ public class Executor<P: PrecisionProtocol>: Executorable{ ...@@ -103,16 +95,12 @@ public class Executor<P: PrecisionProtocol>: Executorable{
//(ops.count - except) //(ops.count - except)
for i in 0..<(ops.count - except) { for i in 0..<(ops.count - except) {
let op = ops[i] let op = ops[i]
do { try op.run(device: device, buffer: buffer)
try op.run(device: device, buffer: buffer)
} catch let error {
throw error
}
} }
var outputTextures: [String : [MTLBuffer]]? var outputTextures: [String : [MTLBuffer]]?
if except > 0 { 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() outputTextures = ops[ops.count - except].inputVariant()
} }
...@@ -153,8 +141,8 @@ public class Executor<P: PrecisionProtocol>: Executorable{ ...@@ -153,8 +141,8 @@ public class Executor<P: PrecisionProtocol>: Executorable{
var resultHolder: GPUResultHolder? var resultHolder: GPUResultHolder?
if except > 0 { if except > 0 {
resultHolder = GPUResultHolder.init(inDim: [], inPointer: nil, inCapacity: 0, inIntermediateResults: outputTextures) resultHolder = GPUResultHolder.init(inDim: [], inPointer: nil, inCapacity: 0, inIntermediateResults: outputTextures)
} else if let output = SSelf.program.scope.output() as? FetchHolder { } else if let output = SSelf.program.scope.output() as? FetchHolder, let outputResult = output.result {
resultHolder = GPUResultHolder.init(inDim: output.dim.dims, inPointer: output.result, inCapacity: output.capacity) resultHolder = GPUResultHolder.init(inDim: output.dim.dims, inPointer: outputResult, inCapacity: output.capacity)
} }
if let resultHolder = resultHolder { if let resultHolder = resultHolder {
safeComplete(true, [resultHolder]) safeComplete(true, [resultHolder])
......
...@@ -27,13 +27,14 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -27,13 +27,14 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
var nowIndex: Int var nowIndex: Int
init(paramPath: String) throws { init(paramPath: String) throws {
guard let tmpFile = fopen(paramPath, "rb") else { 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 file = tmpFile
fseek(file, 0, SEEK_END) fseek(file, 0, SEEK_END)
fileSize = ftell(file) fileSize = ftell(file)
guard fileSize > 0 else { 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) rewind(file)
nowIndex = 0 nowIndex = 0
...@@ -41,7 +42,7 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -41,7 +42,7 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
func read(tensor: Tensor<P>) throws { func read(tensor: Tensor<P>) throws {
guard nowIndex <= fileSize else { 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<T>(type: T.Type) -> T { func pointerReader<T>(type: T.Type) -> T {
...@@ -78,27 +79,26 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -78,27 +79,26 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
var tensorDescFromParams: VarType_TensorDesc? var tensorDescFromParams: VarType_TensorDesc?
do { do {
tensorDescFromParams = try VarType_TensorDesc.init(data: data) tensorDescFromParams = try VarType_TensorDesc.init(data: data)
} catch let error { } catch _ {
print("\(error)")
} }
tensorDescCharArray.deinitialize(count: tensorDescSize) tensorDescCharArray.deinitialize(count: tensorDescSize)
tensorDescCharArray.deallocate() tensorDescCharArray.deallocate()
repeat { repeat {
guard let tensorDescFromParams = tensorDescFromParams, let dimsArrayFromParams = tensorDescFromParams.dimsArray else { guard let tensorDescFromParams = tensorDescFromParams, let dimsArrayFromParams = tensorDescFromParams.dimsArray else {
print("tensorDescFromParams is nil") paddleMobileLog("tensorDescFromParams is nil", logLevel: .FatalError)
break break
} }
if tensorDescFromParams.dimsArray_Count != dimsArrayFromParams.count { 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 break
} }
if tensorDescFromParams.dimsArray_Count != tensor.tensorDim.cout() { 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 break
} }
for i in 0..<dimsArrayFromParams.count { for i in 0..<dimsArrayFromParams.count {
if dimsArrayFromParams.value(at: i) != tensor.tensorDim[Int(i)] { if dimsArrayFromParams.value(at: i) != tensor.tensorDim[Int(i)] {
print("tensorDescFromParams \(String(describing: tensorDescFromParams.dimsArray)) not equal to tensor.tensorDim \(tensor.tensorDim)") paddleMobileLog("tensorDescFromParams \(String(describing: tensorDescFromParams.dimsArray)) not equal to tensor.tensorDim \(tensor.tensorDim)", logLevel: .FatalError)
break break
} }
} }
...@@ -118,7 +118,7 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -118,7 +118,7 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
let bytesRead = fread(tensor.data.pointer, 1, tensor.data.size, file) let bytesRead = fread(tensor.data.pointer, 1, tensor.data.size, file)
guard bytesRead == tensor.data.size else { 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 // TODO: use script to convert
...@@ -147,39 +147,35 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -147,39 +147,35 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
} }
func read(tensor: Tensor<P>) throws { func read(tensor: Tensor<P>) throws {
guard nowIndex <= paramSize else { guard nowIndex < paramSize else {
throw PaddleMobileError.loaderError(message: "out of the file range") throw PaddleMobileError.makeError(type: .loaderError, msg: "out of the file range")
} }
var readerIndex: Int = 0 func pointerReader<T>(type: T.Type) throws -> T {
func pointerReader<T>(type: T.Type) -> T { guard nowIndex + MemoryLayout<T>.size <= paramSize else {
let ptr = UnsafeMutablePointer<T>.allocate(capacity: MemoryLayout<T>.size) throw PaddleMobileError.makeError(type: .loaderError, msg: "must satisfy nowIndex:\(nowIndex)+MemoryLayout<T>.size:\(MemoryLayout<T>.size) <= paramSize:\(paramSize)")
memcpy(ptr, paramPointer.advanced(by: Int(readerIndex)), MemoryLayout<T>.size) }
let ptr = UnsafeMutablePointer<T>.allocate(capacity: 1)
memcpy(ptr, paramPointer.advanced(by: nowIndex), MemoryLayout<T>.size)
nowIndex += MemoryLayout<T>.size nowIndex += MemoryLayout<T>.size
readerIndex += MemoryLayout<T>.size
let pointee = ptr.pointee let pointee = ptr.pointee
ptr.deinitialize(count: MemoryLayout<UInt32>.size) ptr.deinitialize(count: MemoryLayout<UInt32>.size)
ptr.deallocate() ptr.deallocate()
return pointee return pointee
} }
let _ = pointerReader(type: UInt32.self) let _ = try pointerReader(type: UInt32.self)
let lodLevel = pointerReader(type: UInt64.self) let lodLevel = try pointerReader(type: UInt64.self)
for _ in 0..<lodLevel { for _ in 0..<lodLevel {
let size = pointerReader(type: UInt64.self) let size = try pointerReader(type: UInt64.self)
for _ in 0..<Int(size/UInt64(MemoryLayout<size_t>.size)){ for _ in 0..<Int(size/UInt64(MemoryLayout<size_t>.size)){
_ = pointerReader(type: size_t.self) _ = try pointerReader(type: size_t.self)
} }
} }
let _ = pointerReader(type: UInt32.self) let _ = try pointerReader(type: UInt32.self)
let tensorDescSize = pointerReader(type: Int32.self) let tensorDescSize = try pointerReader(type: Int32.self)
paramPointer = paramPointer.advanced(by: Int(readerIndex))
paramPointer = paramPointer.advanced(by: Int(tensorDescSize))
nowIndex += Int(tensorDescSize) nowIndex += Int(tensorDescSize)
let _ = memcpy(tensor.data.pointer, paramPointer, tensor.data.size) let _ = memcpy(tensor.data.pointer, paramPointer.advanced(by: nowIndex), tensor.data.size)
paramPointer = paramPointer.advanced(by: Int(tensor.data.size))
nowIndex += tensor.data.size nowIndex += tensor.data.size
} }
deinit { deinit {
...@@ -195,33 +191,33 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -195,33 +191,33 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
/// oc protobuf serialized Data to instance class /// oc protobuf serialized Data to instance class
let protoProgram = try ProgramDesc.init(data: (modelData as NSData) as Data) let protoProgram = try ProgramDesc.init(data: (modelData as NSData) as Data)
let originProgramDesc = PMProgramDesc.init(protoProgram: protoProgram) let originProgramDesc = try PMProgramDesc.init(protoProgram: protoProgram)
let programDesc = optimize ? ProgramOptimize<P>.init().optimize(originProgramDesc: originProgramDesc) : originProgramDesc let programDesc = optimize ? (ProgramOptimize<P>.init().optimize(originProgramDesc: originProgramDesc) ?? originProgramDesc) : originProgramDesc
// let programDesc = PMProgramDesc.init(protoProgram: protoProgram) // let programDesc = PMProgramDesc.init(protoProgram: protoProgram)
if GlobalConfig.shared.debug { if GlobalConfig.shared.debug {
print(programDesc) paddleMobileLog("\(programDesc)")
} }
guard programDesc.blocks.count > 0 else { 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 // to get feed key and fetch key
let block = programDesc.blocks[0] let block = programDesc.blocks[0]
guard let firstOp = block.ops.first, let lastOp = block.ops.last else { 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 { 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 { 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 { 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) let scope = Scope.init(inFeedKey: feedKey, inFetchKey: fetchKey)
...@@ -231,7 +227,7 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -231,7 +227,7 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
for varDesc in block.vars { for varDesc in block.vars {
if (varDesc.type == .LodTensor) { if (varDesc.type == .LodTensor) {
guard let tensorDesc = varDesc.tensorDesc else { 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 if (varDesc.persistable
...@@ -240,28 +236,25 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -240,28 +236,25 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
let dimArr = tensorDesc.dims let dimArr = tensorDesc.dims
guard dimArr.count > 0 else { 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 dim = Dim.init(inDim: dimArr)
let tensor = Tensor<P>.init(inDim: dim, inLayout: tensorDesc.dataLayout, originDimsCount: tensorDesc.originDimsCount) let tensor = Tensor<P>.init(inDim: dim, inLayout: tensorDesc.dataLayout, originDimsCount: tensorDesc.originDimsCount)
do {
if paraLoaderPointer != nil { if paraLoaderPointer != nil {
try paraLoaderPointer!.read(tensor: tensor) try paraLoaderPointer!.read(tensor: tensor)
} }
if paraLoader != nil { if paraLoader != nil {
try paraLoader!.read(tensor: tensor) try paraLoader!.read(tensor: tensor)
}
} catch let error {
throw error
} }
// tensor.convert(to: DataLayout.NHWC()) // tensor.convert(to: DataLayout.NHWC())
// tensor.initBuffer(device: device) // tensor.initBuffer(device: device)
scope[varDesc.name] = tensor scope[varDesc.name] = tensor
} else { } else {
let dim = Dim.init(inDim: tensorDesc.dims) 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 texture.originDimsCount = tensorDesc.originDimsCount
scope[varDesc.name] = texture scope[varDesc.name] = texture
} }
...@@ -278,35 +271,27 @@ public class Loader<P: PrecisionProtocol>: Loaderable { ...@@ -278,35 +271,27 @@ public class Loader<P: PrecisionProtocol>: Loaderable {
return program return program
} catch _ { } 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 { 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) let modelData = Data.init(bytes:modePointer, count:modelSize)
guard let paraLoader = try? ParaLoaderWithPointer.init(pPointer: paramPointer,pSize: paramSize) else { guard let paraLoader = try? ParaLoaderWithPointer.init(pPointer: paramPointer,pSize: paramSize) else {
throw PaddleMobileError.loaderError(message: "load para error") throw PaddleMobileError.makeError(type: .loaderError, msg: "load para error")
}
do {
let program = try loadModelandParam(device, modelData, paraLoader, nil, optimize)
return program
} catch let error {
throw 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 { 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 { 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 { 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)
let program = try loadModelandParam(device, modelData, nil, paraLoader, optimize) return program
return program
} catch let error {
throw error
}
} }
} }
...@@ -29,15 +29,15 @@ extension Tensorial { ...@@ -29,15 +29,15 @@ extension Tensorial {
} }
class DataConverter<P: PrecisionProtocol> { class DataConverter<P: PrecisionProtocol> {
func convert(from: UnsafeMutablePointer<P>, to: UnsafeMutablePointer<P>, fromDim: Dim) { func convert(from: UnsafeMutablePointer<P>, to: UnsafeMutablePointer<P>, fromDim: Dim) throws {
fatalError(" need imp") throw PaddleMobileError.makeError(type: .memoryError, msg: "DataConverter convert need imp")
} }
func getToDim(fromDim: Dim, layout: DataLayout) -> (dim: Dim, layout: DataLayout) { func getToDim(fromDim: Dim, layout: DataLayout) throws -> (dim: Dim, layout: DataLayout) {
fatalError(" need imp") throw PaddleMobileError.makeError(type: .memoryError, msg: "DataConverter getToDim need imp")
} }
func capacity(fromDim: Dim) -> Int? { func capacity(fromDim: Dim) throws -> Int? {
return nil return nil
} }
} }
...@@ -51,7 +51,7 @@ class MPSPointerConverter<P: PrecisionProtocol>: DataConverter<P>{ ...@@ -51,7 +51,7 @@ class MPSPointerConverter<P: PrecisionProtocol>: DataConverter<P>{
/// - Parameters: /// - Parameters:
/// - from: from pointer /// - from: from pointer
/// - to: to pointer /// - to: to pointer
override func convert(from: UnsafeMutablePointer<P>, to: UnsafeMutablePointer<P>, fromDim: Dim) { override func convert(from: UnsafeMutablePointer<P>, to: UnsafeMutablePointer<P>, fromDim: Dim) throws {
let outputChannels = fromDim[0] let outputChannels = fromDim[0]
let inputChannels = fromDim[1] let inputChannels = fromDim[1]
let kernelHeight = fromDim[2] let kernelHeight = fromDim[2]
...@@ -69,10 +69,10 @@ class MPSPointerConverter<P: PrecisionProtocol>: DataConverter<P>{ ...@@ -69,10 +69,10 @@ class MPSPointerConverter<P: PrecisionProtocol>: DataConverter<P>{
} }
} }
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() { if layout != DataLayout.NCHW() {
fatalError("not support") throw PaddleMobileError.makeError(type: .memoryError, msg: "MPSPointerConverter layout other than NCHW unsupported")
} }
let outputChannels = fromDim[0] let outputChannels = fromDim[0]
...@@ -86,13 +86,13 @@ class MPSPointerConverter<P: PrecisionProtocol>: DataConverter<P>{ ...@@ -86,13 +86,13 @@ class MPSPointerConverter<P: PrecisionProtocol>: DataConverter<P>{
} }
class WinogradPointerConverter<P: PrecisionProtocol>: DataConverter<P>{ class WinogradPointerConverter<P: PrecisionProtocol>: DataConverter<P>{
override func convert(from: UnsafeMutablePointer<P>, to: UnsafeMutablePointer<P>, fromDim: Dim) { override func convert(from: UnsafeMutablePointer<P>, to: UnsafeMutablePointer<P>, fromDim: Dim) throws {
let N = fromDim[0] let N = fromDim[0]
let C = fromDim[1] let C = fromDim[1]
let H = fromDim[2] let H = fromDim[2]
let W = fromDim[3] let W = fromDim[3]
if H != 3 || W != 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..<N { for n in 0..<N {
for c in 0..<C { for c in 0..<C {
...@@ -101,8 +101,8 @@ class WinogradPointerConverter<P: PrecisionProtocol>: DataConverter<P>{ ...@@ -101,8 +101,8 @@ class WinogradPointerConverter<P: PrecisionProtocol>: DataConverter<P>{
func f(_ h: Int, _ w: Int) -> P { func f(_ h: Int, _ w: Int) -> P {
return from[fromOffset + h * W + w] return from[fromOffset + h * W + w]
} }
let c05 = P(Float(0.5)) let c05 = try P(Float(0.5))
let c025 = P(Float(0.25)) let c025 = try P(Float(0.25))
to[toOffset] = f(0, 0); to[toOffset] = f(0, 0);
to[toOffset + 1] = c05 * f(0, 0) to[toOffset + 1] = c05 * f(0, 0)
to[toOffset + 1] = to[toOffset + 1] + c05 * f(0, 1) to[toOffset + 1] = to[toOffset + 1] + c05 * f(0, 1)
...@@ -171,28 +171,28 @@ class WinogradPointerConverter<P: PrecisionProtocol>: DataConverter<P>{ ...@@ -171,28 +171,28 @@ class WinogradPointerConverter<P: PrecisionProtocol>: DataConverter<P>{
} }
} }
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() { if layout != DataLayout.NCHW() {
fatalError("not support") throw PaddleMobileError.makeError(type: .memoryError, msg: "WinogradPointerConverter getToDim only support NCHW")
} }
let N = fromDim[0] let N = fromDim[0]
let C = fromDim[1] let C = fromDim[1]
let H = fromDim[2] let H = fromDim[2]
let W = fromDim[3] let W = fromDim[3]
if H != 3 || W != 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]) let toDim = Dim.init(inDim: [N, C, H + 1, W + 1])
return (dim: toDim, layout: DataLayout.NCHW()) return (dim: toDim, layout: DataLayout.NCHW())
} }
override func capacity(fromDim: Dim) -> Int? { override func capacity(fromDim: Dim) throws -> Int? {
let N = fromDim[0] let N = fromDim[0]
let C = fromDim[1] let C = fromDim[1]
let H = fromDim[2] let H = fromDim[2]
let W = fromDim[3] let W = fromDim[3]
if H != 3 || W != 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) return N * C * (H + 1) * (W + 1)
} }
...@@ -253,12 +253,17 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -253,12 +253,17 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
self.originDimsCount = originDimsCount ?? inDim.cout() self.originDimsCount = originDimsCount ?? inDim.cout()
} }
func convert(converter: DataConverter<P>) -> UnsafeMutablePointer<P> { func convert(converter: DataConverter<P>) throws -> UnsafeMutablePointer<P> {
let toCapacity = converter.capacity(fromDim: dim) ?? numel() let toCapacity = try converter.capacity(fromDim: dim) ?? numel()
let to = UnsafeMutablePointer<P>.allocate(capacity: toCapacity) let to = UnsafeMutablePointer<P>.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) 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 dim = dimAndLayout.dim
layout = dimAndLayout.layout layout = dimAndLayout.layout
return to return to
...@@ -289,13 +294,13 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -289,13 +294,13 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
layout = to 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 { if convertToNHWC {
convert(to: DataLayout.NHWC()) convert(to: DataLayout.NHWC())
} }
if P.precisionType == .Float16 && computePrecision == .Float32{ if P.precisionType == .Float16 && computePrecision == .Float32 {
fatalError(" 不支持: 16位模型不能按照 32 位进行运算") throw PaddleMobileError.makeError(type: .predictError, msg: "Float16 model can not compute in Float32 precision")
} }
if withTranspose { if withTranspose {
...@@ -338,7 +343,7 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -338,7 +343,7 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
case .Float32: case .Float32:
buffer?.contents().copyMemory(from: data.pointer, byteCount: count * MemoryLayout<P>.stride) buffer?.contents().copyMemory(from: data.pointer, byteCount: count * MemoryLayout<P>.stride)
case .Float16: case .Float16:
float32ToFloat16(input: data.pointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: count) try float32ToFloat16(input: data.pointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: count)
} }
} }
} else if C == 1 && !padWhenOneC { } else if C == 1 && !padWhenOneC {
...@@ -351,12 +356,16 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -351,12 +356,16 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
case .Float32: case .Float32:
buffer?.contents().copyMemory(from: data.pointer, byteCount: numel() * MemoryLayout<P>.stride) buffer?.contents().copyMemory(from: data.pointer, byteCount: numel() * MemoryLayout<P>.stride)
case .Float16: case .Float16:
float32ToFloat16(input: data.pointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: numel()) try float32ToFloat16(input: data.pointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: numel())
} }
} }
} else { } else {
buffer = device.makeBuffer(length: count * precisionSize) buffer = device.makeBuffer(length: count * precisionSize)
let convertedPointer = UnsafeMutablePointer<P>.allocate(capacity: count) let convertedPointer = UnsafeMutablePointer<P>.allocate(capacity: count)
defer {
convertedPointer.deinitialize(count: count)
convertedPointer.deallocate()
}
var tmpPointer = data.pointer var tmpPointer = data.pointer
var dstPtr = convertedPointer var dstPtr = convertedPointer
for _ in 0..<dim[0] * dim[1] * dim[2] { for _ in 0..<dim[0] * dim[1] * dim[2] {
...@@ -379,11 +388,9 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -379,11 +388,9 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
case .Float32: case .Float32:
buffer?.contents().copyMemory(from: convertedPointer, byteCount: count * MemoryLayout<P>.stride) buffer?.contents().copyMemory(from: convertedPointer, byteCount: count * MemoryLayout<P>.stride)
case .Float16: case .Float16:
float32ToFloat16(input: convertedPointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: count) try float32ToFloat16(input: convertedPointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: count)
} }
} }
convertedPointer.deinitialize(count: count)
convertedPointer.deallocate()
} }
} else { } else {
let C = dim[3] let C = dim[3]
...@@ -400,14 +407,18 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -400,14 +407,18 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
case .Float32: case .Float32:
buffer?.contents().copyMemory(from: data.pointer, byteCount: count * MemoryLayout<P>.stride) buffer?.contents().copyMemory(from: data.pointer, byteCount: count * MemoryLayout<P>.stride)
case .Float16: case .Float16:
float32ToFloat16(input: data.pointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: count) try float32ToFloat16(input: data.pointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: count)
} }
} }
} else if C == 1 { } else if C == 1 {
fatalError(" not support ") throw PaddleMobileError.makeError(type: .netError, msg: "Tensor initBuffer channel can not be 1")
} else { } else {
buffer = device.makeBuffer(length: count * precisionSize) buffer = device.makeBuffer(length: count * precisionSize)
let convertedPointer = UnsafeMutablePointer<P>.allocate(capacity: count) let convertedPointer = UnsafeMutablePointer<P>.allocate(capacity: count)
defer {
convertedPointer.deinitialize(count: count)
convertedPointer.deallocate()
}
var tmpPointer = data.pointer var tmpPointer = data.pointer
var dstPtr = convertedPointer var dstPtr = convertedPointer
for _ in 0..<dim[0] * dim[1] * dim[2] { for _ in 0..<dim[0] * dim[1] * dim[2] {
...@@ -430,11 +441,9 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -430,11 +441,9 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
case .Float32: case .Float32:
buffer?.contents().copyMemory(from: convertedPointer, byteCount: count * MemoryLayout<P>.stride) buffer?.contents().copyMemory(from: convertedPointer, byteCount: count * MemoryLayout<P>.stride)
case .Float16: case .Float16:
float32ToFloat16(input: convertedPointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: count) try float32ToFloat16(input: convertedPointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: count)
} }
} }
convertedPointer.deinitialize(count: count)
convertedPointer.deallocate()
} }
} }
} else if dim.cout() == 1 { } else if dim.cout() == 1 {
...@@ -449,17 +458,17 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -449,17 +458,17 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
case .Float32: case .Float32:
buffer?.contents().copyMemory(from: data.pointer, byteCount: num * MemoryLayout<P>.stride) buffer?.contents().copyMemory(from: data.pointer, byteCount: num * MemoryLayout<P>.stride)
case .Float16: case .Float16:
float32ToFloat16(input: data.pointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: num) try float32ToFloat16(input: data.pointer as! UnsafeMutablePointer<Float32>, output: buffer.contents(), count: num)
} }
} }
} else { } else {
fatalError(" not support !") throw PaddleMobileError.makeError(type: .netError, msg: "not support tensor initBuffer dim count \(dim.cout())")
} }
//TODO: release
data.release() data.release()
} }
var n: Int {
var n: Int? {
get { get {
if dim.cout() == 4 { if dim.cout() == 4 {
if layout == DataLayout.NCHW() { if layout == DataLayout.NCHW() {
...@@ -467,15 +476,15 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -467,15 +476,15 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
} else if layout == DataLayout.NHWC() { } else if layout == DataLayout.NHWC() {
return dim[0] return dim[0]
} else { } else {
fatalError(" unsupport ") return nil
} }
} else { } else {
fatalError() return nil
} }
} }
} }
var width: Int { var width: Int? {
get { get {
if dim.cout() == 4 { if dim.cout() == 4 {
if layout == DataLayout.NHWC() { if layout == DataLayout.NHWC() {
...@@ -483,15 +492,15 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -483,15 +492,15 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
} else if layout == DataLayout.NCHW() { } else if layout == DataLayout.NCHW() {
return dim[3] return dim[3]
} else { } else {
fatalError(" unsupport ") return nil
} }
} else { } else {
fatalError() return nil
} }
} }
} }
var height: Int { var height: Int? {
get { get {
if dim.cout() == 4 { if dim.cout() == 4 {
if layout == DataLayout.NHWC() { if layout == DataLayout.NHWC() {
...@@ -499,15 +508,15 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -499,15 +508,15 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
} else if layout == DataLayout.NCHW() { } else if layout == DataLayout.NCHW() {
return dim[2] return dim[2]
} else { } else {
fatalError(" unsupport ") return nil
} }
} else { } else {
fatalError() return nil
} }
} }
} }
var channel: Int { var channel: Int? {
get { get {
if dim.cout() == 4 { if dim.cout() == 4 {
if layout == DataLayout.NHWC() { if layout == DataLayout.NHWC() {
...@@ -515,10 +524,10 @@ class Tensor<P: PrecisionProtocol>: Tensorial { ...@@ -515,10 +524,10 @@ class Tensor<P: PrecisionProtocol>: Tensorial {
} else if layout == DataLayout.NCHW() { } else if layout == DataLayout.NCHW() {
return dim[1] return dim[1]
} else { } else {
fatalError(" unsupport ") return nil
} }
} else { } else {
fatalError() return nil
} }
} }
} }
...@@ -559,14 +568,14 @@ extension Tensor { ...@@ -559,14 +568,14 @@ extension Tensor {
} }
func logDataPointer(header: String = "") { func logDataPointer(header: String = "") {
print(header) paddleMobileLog(header)
var str = "" var str = ""
str += "data count: \(data.count) \n" str += "data count: \(data.count) \n"
str += "dim: \(dim) \n" str += "dim: \(dim) \n"
for i in 0..<numel() { for i in 0..<numel() {
str += " \(data.pointer[i])" str += " \(data.pointer[i])"
} }
print(str) paddleMobileLog(str)
} }
var description: String { var description: String {
......
...@@ -76,38 +76,62 @@ public class Texture: Tensorial { ...@@ -76,38 +76,62 @@ public class Texture: Tensorial {
/// tensor dim pad to four /// tensor dim pad to four
public var padToFourDim: Dim public var padToFourDim: Dim
private var textureDesc: MTLTextureDescriptor! private(set) var textureDesc: MTLTextureDescriptor?
public var metalTexture: MTLTexture! public var metalTexture: MTLTexture? {
get {
if _metalTexture == nil, let tmpTextureDesc = textureDesc {
_metalTexture = device.makeTexture(descriptor: tmpTextureDesc)
}
return _metalTexture
}
set {
_metalTexture = newValue
}
}
private var _metalTexture: MTLTexture?
var transpose: [Int] = [0, 1, 2, 3] var transpose: [Int] = [0, 1, 2, 3]
public var device: MTLDevice
func elementCount() -> Int { func elementCount() -> 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] { func toTensor() throws -> [Float32] {
guard padToFourDim.cout() == 4 else { guard padToFourDim.cout() == 4 else {
fatalError("- not support -") 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 { 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 { public func initTexture(device: MTLDevice, inTranspose: [Int] = [0, 1, 2, 3], computePrecision: Precision = .Float16) throws {
transpose = inTranspose transpose = inTranspose
for i in 0..<(4 - tensorDim.cout()) { for i in 0..<(4 - tensorDim.cout()) {
if i != inTranspose[i] { if i != inTranspose[i] {
// fatalError() throw PaddleMobileError.makeError(type: .loaderError, msg: "dims error")
throw PaddleMobileError.loaderError(message: " dims error ")
} }
} }
let newDim = transpose.map { padToFourDim[$0] } let newDim = transpose.map { padToFourDim[$0] }
let newLayout = transpose.map { layout.layoutWithDim[$0] } let newLayout = transpose.map { layout.layoutWithDim[$0] }
...@@ -132,8 +156,7 @@ public class Texture: Tensorial { ...@@ -132,8 +156,7 @@ public class Texture: Tensorial {
tmpTextureDes.height = newDim[2] tmpTextureDes.height = newDim[2]
tmpTextureDes.arrayLength = 1 tmpTextureDes.arrayLength = 1
default: default:
// fatalError("unreachable") throw PaddleMobileError.makeError(type: .loaderError, msg: "unreachable")
throw PaddleMobileError.loaderError(message: " unreachable ")
} }
if computePrecision == .Float16 { if computePrecision == .Float16 {
...@@ -161,10 +184,7 @@ public class Texture: Tensorial { ...@@ -161,10 +184,7 @@ public class Texture: Tensorial {
tmpTextureDes.usage = [.shaderRead, .shaderWrite] tmpTextureDes.usage = [.shaderRead, .shaderWrite]
tmpTextureDes.storageMode = .shared tmpTextureDes.storageMode = .shared
textureDesc = tmpTextureDes textureDesc = tmpTextureDes
guard let inTexture = device.makeTexture(descriptor: tmpTextureDes) else { _metalTexture = nil
throw PaddleMobileError.loaderError(message: " create texture is nil ")
}
metalTexture = inTexture
} }
public func updateDims(inTensorDim: Dim, inDim: Dim) throws { public func updateDims(inTensorDim: Dim, inDim: Dim) throws {
...@@ -179,8 +199,7 @@ public class Texture: Tensorial { ...@@ -179,8 +199,7 @@ public class Texture: Tensorial {
fourDimNum.append(contentsOf: inDim.dims) fourDimNum.append(contentsOf: inDim.dims)
fourDim = Dim.init(inDim: fourDimNum) fourDim = Dim.init(inDim: fourDimNum)
} else { } else {
// fatalError(" not support ") throw PaddleMobileError.makeError(type: .loaderError, msg: "not support")
throw PaddleMobileError.loaderError(message: " not support ")
} }
tensorDim = inTensorDim tensorDim = inTensorDim
...@@ -189,10 +208,11 @@ public class Texture: Tensorial { ...@@ -189,10 +208,11 @@ public class Texture: Tensorial {
} }
// 初始化时 dim padToFourDim 模型中的维度(一般来说 nchw),前面补全0 // 初始化时 dim padToFourDim 模型中的维度(一般来说 nchw),前面补全0
init(device: MTLDevice, inDim: Dim) { init(device: MTLDevice, inDim: Dim) throws {
if GlobalConfig.shared.debug { if GlobalConfig.shared.debug {
print(" in dim > \(inDim)") print(" in dim > \(inDim)")
} }
self.device = device
var fourDim: Dim var fourDim: Dim
if inDim.cout() == 4 { if inDim.cout() == 4 {
fourDim = inDim fourDim = inDim
...@@ -204,7 +224,7 @@ public class Texture: Tensorial { ...@@ -204,7 +224,7 @@ public class Texture: Tensorial {
fourDimNum.append(contentsOf: inDim.dims) fourDimNum.append(contentsOf: inDim.dims)
fourDim = Dim.init(inDim: fourDimNum) fourDim = Dim.init(inDim: fourDimNum)
} else { } else {
fatalError(" not support ") throw PaddleMobileError.makeError(type: .netError, msg: "Texture init: dim count \(inDim) unsupported")
} }
tensorDim = inDim tensorDim = inDim
dim = fourDim dim = fourDim
...@@ -223,9 +243,20 @@ extension Texture { ...@@ -223,9 +243,20 @@ extension Texture {
public var debugDescription: String{ public var debugDescription: String{
var str = "" var str = ""
str += "Dim: \(dim) \n value:[ " str += "Dim: \(dim) \n value:[ "
str += "\(metalTexture.description)" str += "\(_metalTexture?.description ?? "")"
str += " ]" str += " ]"
return 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)
}
}
} }
/* 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<String>? = 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)
}
...@@ -29,14 +29,10 @@ class OpCreator<P: PrecisionProtocol> { ...@@ -29,14 +29,10 @@ class OpCreator<P: PrecisionProtocol> {
func creat(device: MTLDevice, opDesc: PMOpDesc, scope: Scope, initContext: InitContext) throws -> Runable & InferShaperable { func creat(device: MTLDevice, opDesc: PMOpDesc, scope: Scope, initContext: InitContext) throws -> Runable & InferShaperable {
guard let opCreator = opCreators[opDesc.type] else { 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)
return try opCreator(device, opDesc, scope, initContext)
} catch let error {
throw error
}
} }
let opCreators: [String : (MTLDevice, PMOpDesc, Scope, InitContext) throws -> Runable & InferShaperable] = let opCreators: [String : (MTLDevice, PMOpDesc, Scope, InitContext) throws -> Runable & InferShaperable] =
......
...@@ -61,159 +61,98 @@ extension OpParam { ...@@ -61,159 +61,98 @@ extension OpParam {
static func getFirstTensor<VarType: Variant>(key: String, map: [String : [String]], from: Scope) throws -> VarType { static func getFirstTensor<VarType: Variant>(key: String, map: [String : [String]], from: Scope) throws -> VarType {
guard let mapKeys = map[key], mapKeys.count > 0 else { 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 { 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 { guard let v = variant as? VarType else {
throw PaddleMobileError.paramError(message: " type error") throw PaddleMobileError.makeError(type: .paramError, msg: "type error")
} }
return v return v
} }
static func outputVariances<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType { static func outputVariances<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorVariances: VarType = try getFirstTensor(key: "Variances", map: outputs, from: from)
let tensorVariances: VarType = try getFirstTensor(key: "Variances", map: outputs, from: from) return tensorVariances
return tensorVariances
} catch let error {
throw error
}
} }
static func paramInputAlpha<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func paramInputAlpha<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let alphaTensor: VarType = try getFirstTensor(key: "Alpha", map: inputs, from: from)
let alphaTensor: VarType = try getFirstTensor(key: "Alpha", map: inputs, from: from) return alphaTensor
return alphaTensor
} catch let error {
throw error
}
} }
static func inputImage<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func inputImage<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorImage: VarType = try getFirstTensor(key: "Image", map: inputs, from: from)
let tensorImage: VarType = try getFirstTensor(key: "Image", map: inputs, from: from) return tensorImage
return tensorImage
} catch let error {
throw error
}
} }
static func inputX<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func inputX<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorX: VarType = try getFirstTensor(key: "X", map: inputs, from: from)
let tensorX: VarType = try getFirstTensor(key: "X", map: inputs, from: from) return tensorX
return tensorX
} catch let error {
throw error
}
} }
static func outputBoxes<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType { static func outputBoxes<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorBox: VarType = try getFirstTensor(key: "Boxes", map: outputs, from: from)
let tensorBox: VarType = try getFirstTensor(key: "Boxes", map: outputs, from: from) return tensorBox
return tensorBox
} catch let error {
throw error
}
} }
static func input<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func input<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorInput: VarType = try getFirstTensor(key: "Input", map: inputs, from: from)
let tensorInput: VarType = try getFirstTensor(key: "Input", map: inputs, from: from) return tensorInput
return tensorInput
} catch let error {
throw error
}
} }
static func output<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType { static func output<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorOutput: VarType = try getFirstTensor(key: "Output", map: outputs, from: from)
let tensorOutput: VarType = try getFirstTensor(key: "Output", map: outputs, from: from) return tensorOutput
return tensorOutput
} catch let error {
throw error
}
} }
static func outputY<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType { static func outputY<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorOutputY: VarType = try getFirstTensor(key: "Y", map: outputs, from: from)
let tensorOutputY: VarType = try getFirstTensor(key: "Y", map: outputs, from: from) return tensorOutputY
return tensorOutputY
} catch let error {
throw error
}
} }
static func inputY<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func inputY<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorY: VarType = try getFirstTensor(key: "Y", map: inputs, from: from)
let tensorY: VarType = try getFirstTensor(key: "Y", map: inputs, from: from) return tensorY
return tensorY
} catch let error {
throw error
}
} }
static func outputOut<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType { static func outputOut<VarType: Variant>(outputs: [String : [String]], from: Scope) throws -> VarType {
do { let out: VarType = try getFirstTensor(key: "Out", map: outputs, from: from)
let out: VarType = try getFirstTensor(key: "Out", map: outputs, from: from) return out
return out
} catch let error {
throw error
}
} }
static func inputFilter<VarType: Variant>(paraInputs: [String : [String]], from: Scope) throws -> VarType { static func inputFilter<VarType: Variant>(paraInputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorFilter: VarType = try getFirstTensor(key: "Filter", map: paraInputs, from: from)
let tensorFilter: VarType = try getFirstTensor(key: "Filter", map: paraInputs, from: from) return tensorFilter
return tensorFilter
} catch let error {
throw error
}
} }
static func inputBiase<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func inputBiase<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorBias: VarType = try getFirstTensor(key: "Bias", map: inputs, from: from)
let tensorBias: VarType = try getFirstTensor(key: "Bias", map: inputs, from: from) return tensorBias
return tensorBias
} catch let error {
throw error
}
} }
static func inputMean<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func inputMean<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorMean: VarType = try getFirstTensor(key: "Mean", map: inputs, from: from)
let tensorMean: VarType = try getFirstTensor(key: "Mean", map: inputs, from: from) return tensorMean
return tensorMean
} catch let error {
throw error
}
} }
static func inputScale<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func inputScale<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorScale: VarType = try getFirstTensor(key: "Scale", map: inputs, from: from)
let tensorScale: VarType = try getFirstTensor(key: "Scale", map: inputs, from: from) return tensorScale
return tensorScale
} catch let error {
throw error
}
} }
static func inputVariance<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType { static func inputVariance<VarType: Variant>(inputs: [String : [String]], from: Scope) throws -> VarType {
do { let tensorVariance: VarType = try getFirstTensor(key: "Variance", map: inputs, from: from)
let tensorVariance: VarType = try getFirstTensor(key: "Variance", map: inputs, from: from) return tensorVariance
return tensorVariance
} catch let error {
throw error
}
} }
static func getAttr<T>(key: String, attrs: [String : Attr]) throws -> T{ static func getAttr<T>(key: String, attrs: [String : Attr]) throws -> T {
guard let attr = attrs[key] else { 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 { 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 return tAttr
} }
......
...@@ -31,30 +31,25 @@ protocol Runable { ...@@ -31,30 +31,25 @@ protocol Runable {
func run(device: MTLDevice, buffer: MTLCommandBuffer) throws func run(device: MTLDevice, buffer: MTLCommandBuffer) throws
func runImpl(device: MTLDevice,buffer: MTLCommandBuffer) throws func runImpl(device: MTLDevice,buffer: MTLCommandBuffer) throws
func delogOutput() func delogOutput()
func inputVariant() -> [String : [MTLBuffer]] func inputVariant() -> [String : [MTLBuffer]]?
func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) throws
} }
extension Runable where Self: OperatorProtocol{ extension Runable where Self: OperatorProtocol {
func run(device: MTLDevice, buffer: MTLCommandBuffer) throws { func run(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do { try runImpl(device: device, buffer: buffer)
try runImpl(device: device, buffer: buffer)
} catch let error {
throw error
}
} }
func inputVariant() -> [String : [MTLBuffer]] { func inputVariant() -> [String : [MTLBuffer]]? {
// return [:] // return [:]
fatalError(" op \(type) need implement inputVariant") return nil
} }
func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) { func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) throws {
fatalError(" need implement ") throw PaddleMobileError.makeError(type: .netError, msg: "need implement func computeMiddleResult")
} }
func delogOutput() { func delogOutput() {
print(type + ": has no implementation" ) print(type + ": has no implementation" )
} }
} }
...@@ -86,11 +81,7 @@ protocol Creator where Self: OperatorProtocol{ ...@@ -86,11 +81,7 @@ protocol Creator where Self: OperatorProtocol{
extension Creator where Self: OperatorProtocol { extension Creator where Self: OperatorProtocol {
static func creat(device: MTLDevice, opDesc: PMOpDesc, inScope: Scope, initContext: InitContext) throws -> OpType { 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)
return try OpType.provide(device:device, opDesc: opDesc, inScope: inScope, initContext: initContext)
} catch let error {
throw error
}
} }
} }
...@@ -114,11 +105,7 @@ protocol OperatorProtocol { ...@@ -114,11 +105,7 @@ protocol OperatorProtocol {
extension OperatorProtocol { extension OperatorProtocol {
static func provide(device: MTLDevice, opDesc: PMOpDesc, inScope: Scope, initContext: InitContext) throws -> Self { 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)
return try Self.init(device: device, opDesc: opDesc, inScope: inScope, initContext: initContext)
} catch let error {
throw error
}
} }
} }
...@@ -130,12 +117,8 @@ class Operator <KernelType: Computable , ParameterType>: OperatorProtocol where ...@@ -130,12 +117,8 @@ class Operator <KernelType: Computable , ParameterType>: OperatorProtocol where
outpus = opDesc.outputs outpus = opDesc.outputs
attrs = opDesc.attrs attrs = opDesc.attrs
paraInputs = opDesc.paraInputs paraInputs = opDesc.paraInputs
do { para = try ParamType.init(opDesc:opDesc, inScope: inScope)
para = try ParamType.init(opDesc:opDesc, inScope: inScope) kernel = try KernelType.init(device: device, param: para, initContext: initContext)
kernel = try KernelType.init(device: device, param: para, initContext: initContext)
} catch let error {
throw error
}
} }
typealias ParamType = ParameterType typealias ParamType = ParameterType
......
...@@ -18,21 +18,17 @@ import Metal ...@@ -18,21 +18,17 @@ import Metal
class BatchNormParam<P: PrecisionProtocol>: OpParam { class BatchNormParam<P: PrecisionProtocol>: OpParam {
//typealias ParamPrecisionType = P //typealias ParamPrecisionType = P
required init(opDesc: PMOpDesc, inScope: Scope) throws { required init(opDesc: PMOpDesc, inScope: Scope) throws {
do { input = try BatchNormParam.inputX(inputs: opDesc.inputs, from: inScope)
input = try BatchNormParam.inputX(inputs: opDesc.inputs, from: inScope) if input.transpose != [0, 2, 3, 1] {
if input.transpose != [0, 2, 3, 1] { throw PaddleMobileError.makeError(type: .netError, msg: "batch norm only accepts NHWC")
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
} }
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 let input: Texture
var output: Texture var output: Texture
...@@ -51,17 +47,11 @@ class BatchNormOp<P: PrecisionProtocol>: Operator<BatchNormKernel<P>, BatchNormP ...@@ -51,17 +47,11 @@ class BatchNormOp<P: PrecisionProtocol>: Operator<BatchNormKernel<P>, BatchNormP
para.output.dim = para.input.dim para.output.dim = para.input.dim
} }
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do { try kernel.compute(commandBuffer: buffer, param: para)
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
} }
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
let device = para.output.metalTexture!.device para.output.delog()
let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
print(outputArray.strideArray())
} }
} }
...@@ -18,16 +18,12 @@ import Metal ...@@ -18,16 +18,12 @@ import Metal
class BilinearInterpParam<P: PrecisionProtocol>: OpParam { class BilinearInterpParam<P: PrecisionProtocol>: OpParam {
//typealias ParamPrecisionType = P //typealias ParamPrecisionType = P
required init(opDesc: PMOpDesc, inScope: Scope) throws { required init(opDesc: PMOpDesc, inScope: Scope) throws {
do { input = try BilinearInterpParam.inputX(inputs: opDesc.inputs, from: inScope)
input = try BilinearInterpParam.inputX(inputs: opDesc.inputs, from: inScope) output = try BilinearInterpParam.outputOut(outputs: opDesc.outputs, from: inScope)
output = try BilinearInterpParam.outputOut(outputs: opDesc.outputs, from: inScope) out_h = try BilinearInterpParam.getAttr(key: "out_h", attrs: opDesc.attrs)
out_h = try BilinearInterpParam.getAttr(key: "out_h", attrs: opDesc.attrs) out_w = try BilinearInterpParam.getAttr(key: "out_w", attrs: opDesc.attrs)
out_w = try BilinearInterpParam.getAttr(key: "out_w", attrs: opDesc.attrs)
} catch let error {
throw error
}
if (input.transpose != [0, 2, 3, 1]) || (input.tensorDim.cout() != 4) { 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 let input: Texture
...@@ -45,19 +41,12 @@ class BilinearInterpOp<P: PrecisionProtocol>: Operator<BilinearInterpKernel<P>, ...@@ -45,19 +41,12 @@ class BilinearInterpOp<P: PrecisionProtocol>: Operator<BilinearInterpKernel<P>,
} }
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do { try kernel.compute(commandBuffer: buffer, param: para)
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
} }
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
let device = para.output.metalTexture!.device para.output.delog()
let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
// print(outputArray)
print(outputArray.strideArray())
} }
} }
......
...@@ -17,25 +17,26 @@ import Foundation ...@@ -17,25 +17,26 @@ import Foundation
class BoxcoderParam<P: PrecisionProtocol>: OpParam { class BoxcoderParam<P: PrecisionProtocol>: OpParam {
//typealias ParamPrecisionType = P //typealias ParamPrecisionType = P
required init(opDesc: PMOpDesc, inScope: Scope) throws { required init(opDesc: PMOpDesc, inScope: Scope) throws {
do { priorBox = try BoxcoderParam.getFirstTensor(key: "PriorBox", map: opDesc.inputs, from: inScope)
priorBox = try BoxcoderParam.getFirstTensor(key: "PriorBox", map: opDesc.inputs, from: inScope) priorBoxVar = try BoxcoderParam.getFirstTensor(key: "PriorBoxVar", 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)
targetBox = try BoxcoderParam.getFirstTensor(key: "TargetBox", map: opDesc.inputs, from: inScope) output = try BoxcoderParam.getFirstTensor(key: "OutputBox", map: opDesc.outputs, from: inScope)
output = try BoxcoderParam.getFirstTensor(key: "OutputBox", map: opDesc.outputs, from: inScope) codeType = try BoxcoderParam.getAttr(key: "code_type", attrs: opDesc.attrs)
codeType = try BoxcoderParam.getAttr(key: "code_type", attrs: opDesc.attrs) boxNormalized = try BoxcoderParam.getAttr(key: "box_normalized", attrs: opDesc.attrs)
boxNormalized = try BoxcoderParam.getAttr(key: "box_normalized", attrs: opDesc.attrs)
} catch let error { guard priorBox.tensorDim.cout() == 2 &&
throw error 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 priorBox: Texture
let priorBoxVar: Texture let priorBoxVar: Texture
...@@ -54,28 +55,19 @@ class BoxcoderOp<P: PrecisionProtocol>: Operator<BoxcoderKernel<P>, BoxcoderPara ...@@ -54,28 +55,19 @@ class BoxcoderOp<P: PrecisionProtocol>: Operator<BoxcoderKernel<P>, BoxcoderPara
} }
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do { try kernel.compute(commandBuffer: buffer, param: para)
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
} }
func delogOutput() { func delogOutput() {
print(" \(type) output: ") 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(" prior box var ")
print(pbv.strideArray()) para.priorBoxVar.delog()
print(" target box ") print(" target box ")
print(tb.strideArray()) para.targetBox.delog()
print(" prior box ") print(" prior box ")
print(pb.strideArray()) para.priorBox.delog()
print(" output ") print(" output ")
print(out.strideArray()) para.output.delog()
} }
} }
......
...@@ -17,37 +17,33 @@ import Foundation ...@@ -17,37 +17,33 @@ import Foundation
class ConcatParam<P: PrecisionProtocol>: OpParam { class ConcatParam<P: PrecisionProtocol>: OpParam {
//typealias ParamPrecisionType = P //typealias ParamPrecisionType = P
required init(opDesc: PMOpDesc, inScope: Scope) throws { required init(opDesc: PMOpDesc, inScope: Scope) throws {
do { guard let xlist = opDesc.inputs["X"] else {
guard let xlist = opDesc.inputs["X"] else { throw PaddleMobileError.makeError(type: .netError, msg: "concat input desc nil")
fatalError() }
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 { if transpose.count == 0 {
guard let variant = inScope[x], let v = variant as? Texture else { transpose = v.transpose
fatalError()
}
if transpose.count == 0 {
transpose = v.transpose
}
if v.transpose != transpose {
fatalError()
}
input.append(v)
} }
axis = try ConcatParam.getAttr(key: "axis", attrs: opDesc.attrs) if v.transpose != transpose {
if input.count > 0 { throw PaddleMobileError.makeError(type: .netError, msg: "concat transpose not equal")
if let originDimsCount = input[0].originDimsCount { }
let nowDimsCount = input[0].dim.cout()
let diff = originDimsCount - nowDimsCount input.append(v)
if diff > 0 { }
axis -= diff 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 input: [Texture] = []
var output: Texture var output: Texture
...@@ -65,19 +61,12 @@ class ConcatOp<P: PrecisionProtocol>: Operator<ConcatKernel<P>, ConcatParam<P>>, ...@@ -65,19 +61,12 @@ class ConcatOp<P: PrecisionProtocol>: Operator<ConcatKernel<P>, ConcatParam<P>>,
} }
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do { try kernel.compute(commandBuffer: buffer, param: para)
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
} }
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
para.output.delog()
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())
} }
} }
......
...@@ -18,20 +18,16 @@ import Metal ...@@ -18,20 +18,16 @@ import Metal
class ConvAddAddPreluParam<P: PrecisionProtocol>: OpParam { class ConvAddAddPreluParam<P: PrecisionProtocol>: OpParam {
//typealias ParamPrecisionType = P //typealias ParamPrecisionType = P
required init(opDesc: PMOpDesc, inScope: Scope) throws { required init(opDesc: PMOpDesc, inScope: Scope) throws {
do { filter = try ConvAddAddPreluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope)
filter = try ConvAddAddPreluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) input = try ConvAddAddPreluParam.input(inputs: opDesc.inputs, from: inScope)
input = try ConvAddAddPreluParam.input(inputs: opDesc.inputs, from: inScope) output = try ConvAddAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope)
output = try ConvAddAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope) stride = try ConvAddAddPreluParam.getAttr(key: "strides", attrs: opDesc.attrs)
stride = try ConvAddAddPreluParam.getAttr(key: "strides", attrs: opDesc.attrs) paddings = try ConvAddAddPreluParam.getAttr(key: "paddings", attrs: opDesc.attrs)
paddings = try ConvAddAddPreluParam.getAttr(key: "paddings", attrs: opDesc.attrs) dilations = try ConvAddAddPreluParam.getAttr(key: "dilations", attrs: opDesc.attrs)
dilations = try ConvAddAddPreluParam.getAttr(key: "dilations", attrs: opDesc.attrs) groups = try ConvAddAddPreluParam.getAttr(key: "groups", attrs: opDesc.attrs)
groups = try ConvAddAddPreluParam.getAttr(key: "groups", attrs: opDesc.attrs) alpha = try ConvAddAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope)
alpha = try ConvAddAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope) mode = try ConvAddAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs)
mode = try ConvAddAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs) y = try ConvAddAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope)
y = try ConvAddAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope)
} catch let error {
throw error
}
} }
let input: Texture let input: Texture
...@@ -93,17 +89,17 @@ class ConvAddAddPreluOp<P: PrecisionProtocol>: Operator<ConvAddAddPreluKernel<P> ...@@ -93,17 +89,17 @@ class ConvAddAddPreluOp<P: PrecisionProtocol>: Operator<ConvAddAddPreluKernel<P>
} }
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do { try kernel.compute(commandBuffer: buffer, param: para)
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
} }
func delogOutput() { func delogOutput() {
print(" \(type) output: ") 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 _ {
}
} }
} }
...@@ -18,26 +18,21 @@ import Foundation ...@@ -18,26 +18,21 @@ import Foundation
class ConvAddBatchNormReluParam<P: PrecisionProtocol>: OpParam { class ConvAddBatchNormReluParam<P: PrecisionProtocol>: OpParam {
//typealias ParamPrecisionType = P //typealias ParamPrecisionType = P
required init(opDesc: PMOpDesc, inScope: Scope) throws { 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)
filter = try ConvAddBatchNormReluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope) output = try ConvAddBatchNormReluParam.outputOut(outputs: opDesc.outputs, from: inScope)
input = try ConvAddBatchNormReluParam.input(inputs: opDesc.inputs, from: inScope) stride = try ConvAddBatchNormReluParam.getAttr(key: "strides", attrs: opDesc.attrs)
output = try ConvAddBatchNormReluParam.outputOut(outputs: opDesc.outputs, from: inScope) paddings = try ConvAddBatchNormReluParam.getAttr(key: "paddings", attrs: opDesc.attrs)
stride = try ConvAddBatchNormReluParam.getAttr(key: "strides", attrs: opDesc.attrs) dilations = try ConvAddBatchNormReluParam.getAttr(key: "dilations", attrs: opDesc.attrs)
paddings = try ConvAddBatchNormReluParam.getAttr(key: "paddings", attrs: opDesc.attrs) epsilon = try ConvAddBatchNormReluParam.getAttr(key: "epsilon", 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)
groups = try ConvAddBatchNormReluParam.getAttr(key: "groups", attrs: opDesc.attrs) bias = try ConvAddBatchNormReluParam.inputBiase(inputs: opDesc.paraInputs, from: inScope)
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)
scale = try ConvAddBatchNormReluParam.inputScale(inputs: opDesc.paraInputs, from: inScope) y = try ConvAddBatchNormReluParam.inputY(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
}
} }
let input: Texture let input: Texture
...@@ -86,11 +81,7 @@ class ConvAddBatchNormReluOp<P: PrecisionProtocol>: Operator<ConvAddBatchNormRel ...@@ -86,11 +81,7 @@ class ConvAddBatchNormReluOp<P: PrecisionProtocol>: Operator<ConvAddBatchNormRel
} }
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do { try kernel.compute(commandBuffer: buffer, param: para)
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
} }
static func fusionNode() -> Node { static func fusionNode() -> Node {
...@@ -112,7 +103,11 @@ class ConvAddBatchNormReluOp<P: PrecisionProtocol>: Operator<ConvAddBatchNormRel ...@@ -112,7 +103,11 @@ class ConvAddBatchNormReluOp<P: PrecisionProtocol>: Operator<ConvAddBatchNormRel
func delogOutput() { func delogOutput() {
print(" conv add batchnorm relu output ") print(" conv add batchnorm relu output ")
print(para.output.toTensor().strideArray()) do {
let output = try para.output.toTensor().strideArray()
print(output)
} catch _ {
}
// let _: P? = para.input.metalTexture.logDesc(header: "conv add batchnorm relu input: ", stridable: false) // let _: P? = para.input.metalTexture.logDesc(header: "conv add batchnorm relu input: ", stridable: false)
// para.filter.logDataPointer(header: "filter data pointer: ") // para.filter.logDataPointer(header: "filter data pointer: ")
// print("filter: \(para.filter)") // print("filter: \(para.filter)")
......
...@@ -55,16 +55,16 @@ class ConvAddOp<P: PrecisionProtocol>: Operator<ConvAddKernel<P>, ConvAddReluPar ...@@ -55,16 +55,16 @@ class ConvAddOp<P: PrecisionProtocol>: Operator<ConvAddKernel<P>, ConvAddReluPar
} }
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do { try kernel.compute(commandBuffer: buffer, param: para)
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
} }
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
print(para.output.metalTexture) 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 _ {
}
} }
} }
...@@ -64,7 +64,10 @@ class ConvReluOp<P: PrecisionProtocol>: Operator<ConvReluKernel<P>, ConvAddReluP ...@@ -64,7 +64,10 @@ class ConvReluOp<P: PrecisionProtocol>: Operator<ConvReluKernel<P>, ConvAddReluP
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
print(para.output.metalTexture) do {
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 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 _ {
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册