提交 b7a1d552 编写于 作者: X xiaohaichun

merge metal branch to pointer

...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*.lai *.lai
*.la *.la
*.lib *.lib
*.a
# Executables # Executables
*.exe *.exe
......
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
FCEB6843212F00CC00D2448E /* PreluKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FCEB6842212F00CC00D2448E /* PreluKernel.metal */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
FCEB683F212F00CC00D2448E /* PreluKernel.metallib */ = {isa = PBXFileReference; explicitFileType = "archive.metal-library"; includeInIndex = 0; path = PreluKernel.metallib; sourceTree = BUILT_PRODUCTS_DIR; };
FCEB6842212F00CC00D2448E /* PreluKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = PreluKernel.metal; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
FCEB6838212F00CC00D2448E = {
isa = PBXGroup;
children = (
FCEB6841212F00CC00D2448E /* PreluKernel */,
FCEB6840212F00CC00D2448E /* Products */,
);
sourceTree = "<group>";
};
FCEB6840212F00CC00D2448E /* Products */ = {
isa = PBXGroup;
children = (
FCEB683F212F00CC00D2448E /* PreluKernel.metallib */,
);
name = Products;
sourceTree = "<group>";
};
FCEB6841212F00CC00D2448E /* PreluKernel */ = {
isa = PBXGroup;
children = (
FCEB6842212F00CC00D2448E /* PreluKernel.metal */,
);
path = PreluKernel;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
FCEB683E212F00CC00D2448E /* PreluKernel */ = {
isa = PBXNativeTarget;
buildConfigurationList = FCEB6846212F00CC00D2448E /* Build configuration list for PBXNativeTarget "PreluKernel" */;
buildPhases = (
FCEB683D212F00CC00D2448E /* Sources */,
);
buildRules = (
);
dependencies = (
);
name = PreluKernel;
productName = PreluKernel;
productReference = FCEB683F212F00CC00D2448E /* PreluKernel.metallib */;
productType = "com.apple.product-type.metal-library";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
FCEB6839212F00CC00D2448E /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = orange;
TargetAttributes = {
FCEB683E212F00CC00D2448E = {
CreatedOnToolsVersion = 9.4.1;
};
};
};
buildConfigurationList = FCEB683C212F00CC00D2448E /* Build configuration list for PBXProject "PreluKernel" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = FCEB6838212F00CC00D2448E;
productRefGroup = FCEB6840212F00CC00D2448E /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
FCEB683E212F00CC00D2448E /* PreluKernel */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
FCEB683D212F00CC00D2448E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FCEB6843212F00CC00D2448E /* PreluKernel.metal in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
FCEB6844212F00CC00D2448E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
MTL_ENABLE_DEBUG_INFO = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
FCEB6845212F00CC00D2448E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
IPHONEOS_DEPLOYMENT_TARGET = 11.4;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
};
name = Release;
};
FCEB6847212F00CC00D2448E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = Z5M2UUN5YV;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
FCEB6848212F00CC00D2448E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = Z5M2UUN5YV;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
FCEB683C212F00CC00D2448E /* Build configuration list for PBXProject "PreluKernel" */ = {
isa = XCConfigurationList;
buildConfigurations = (
FCEB6844212F00CC00D2448E /* Debug */,
FCEB6845212F00CC00D2448E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
FCEB6846212F00CC00D2448E /* Build configuration list for PBXNativeTarget "PreluKernel" */ = {
isa = XCConfigurationList;
buildConfigurations = (
FCEB6847212F00CC00D2448E /* Debug */,
FCEB6848212F00CC00D2448E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = FCEB6839212F00CC00D2448E /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:PreluKernel.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"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>PreluKernel.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>
//
// PreluKernel.metal
// PreluKernel
//
// Created by liuRuiLong on 2018/8/23.
// Copyright © 2018年 orange. All rights reserved.
//
#include <metal_stdlib>
using namespace metal;
...@@ -8,234 +8,31 @@ ...@@ -8,234 +8,31 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
30D0ED21F392CFA3885B1002 /* Pods_paddle_mobile_demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18896810981724F8A0FED62A /* Pods_paddle_mobile_demo.framework */; }; 30D0ED21F392CFA3885B1002 /* Pods_paddle_mobile_demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18896810981724F8A0FED62A /* Pods_paddle_mobile_demo.framework */; };
C23717882148E5A50092444E /* ar_model in Resources */ = {isa = PBXBuildFile; fileRef = C23717862148E5A50092444E /* ar_model */; };
C23717892148E5A50092444E /* ar_params in Resources */ = {isa = PBXBuildFile; fileRef = C23717872148E5A50092444E /* ar_params */; };
C2C08E3B2142748D00C69DBF /* synset.txt in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D5B2142748D00C69DBF /* synset.txt */; };
C2C08E3C2142748D00C69DBF /* banana.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D5C2142748D00C69DBF /* banana.jpeg */; };
C2C08E3D2142748D00C69DBF /* hand.jpg in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D5D2142748D00C69DBF /* hand.jpg */; };
C2C08E3E2142748D00C69DBF /* iphone.JPG in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D5E2142748D00C69DBF /* iphone.JPG */; };
C2C08E3F2142748D00C69DBF /* paddle-mobile.png in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D5F2142748D00C69DBF /* paddle-mobile.png */; };
C2C08E402142748D00C69DBF /* params in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D622142748D00C69DBF /* params */; };
C2C08E412142748D00C69DBF /* model in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D632142748D00C69DBF /* model */; };
C2C08E422142748D00C69DBF /* genet_params in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D652142748D00C69DBF /* genet_params */; };
C2C08E432142748D00C69DBF /* genet_model in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D662142748D00C69DBF /* genet_model */; };
C2C08E442142748D00C69DBF /* ssd_hand_params in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D682142748D00C69DBF /* ssd_hand_params */; };
C2C08E452142748D00C69DBF /* ssd_hand_model in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D692142748D00C69DBF /* ssd_hand_model */; };
C2C08E462142748D00C69DBF /* mobilenet in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D6B2142748D00C69DBF /* mobilenet */; };
C2C08E472142748D00C69DBF /* params in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D6C2142748D00C69DBF /* params */; };
C2C08E482142748D00C69DBF /* model in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D6D2142748D00C69DBF /* model */; };
C2C08E492142748D00C69DBF /* yolo in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D6E2142748D00C69DBF /* yolo */; };
C2C08E4A2142748D00C69DBF /* params in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D702142748D00C69DBF /* params */; };
C2C08E4B2142748D00C69DBF /* model in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D712142748D00C69DBF /* model */; };
C2C08E4C2142748D00C69DBF /* batch_norm_7.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D732142748D00C69DBF /* batch_norm_7.w_0 */; };
C2C08E4D2142748D00C69DBF /* batch_norm_26.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D742142748D00C69DBF /* batch_norm_26.b_0 */; };
C2C08E4E2142748D00C69DBF /* batch_norm_32.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D752142748D00C69DBF /* batch_norm_32.b_0 */; };
C2C08E4F2142748D00C69DBF /* conv2d_16.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D762142748D00C69DBF /* conv2d_16.w_0 */; };
C2C08E502142748D00C69DBF /* batch_norm_15.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D772142748D00C69DBF /* batch_norm_15.w_2 */; };
C2C08E512142748D00C69DBF /* batch_norm_29.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D782142748D00C69DBF /* batch_norm_29.w_2 */; };
C2C08E522142748D00C69DBF /* batch_norm_4.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D792142748D00C69DBF /* batch_norm_4.w_1 */; };
C2C08E532142748D00C69DBF /* batch_norm_5.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D7A2142748D00C69DBF /* batch_norm_5.w_1 */; };
C2C08E542142748D00C69DBF /* batch_norm_28.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D7B2142748D00C69DBF /* batch_norm_28.w_2 */; };
C2C08E552142748D00C69DBF /* batch_norm_14.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D7C2142748D00C69DBF /* batch_norm_14.w_2 */; };
C2C08E562142748D00C69DBF /* conv2d_17.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D7D2142748D00C69DBF /* conv2d_17.w_0 */; };
C2C08E572142748D00C69DBF /* batch_norm_33.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D7E2142748D00C69DBF /* batch_norm_33.b_0 */; };
C2C08E582142748D00C69DBF /* batch_norm_27.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D7F2142748D00C69DBF /* batch_norm_27.b_0 */; };
C2C08E592142748D00C69DBF /* batch_norm_6.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D802142748D00C69DBF /* batch_norm_6.w_0 */; };
C2C08E5A2142748D00C69DBF /* batch_norm_4.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D812142748D00C69DBF /* batch_norm_4.w_0 */; };
C2C08E5B2142748D00C69DBF /* depthwise_conv2d_9.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D822142748D00C69DBF /* depthwise_conv2d_9.w_0 */; };
C2C08E5C2142748D00C69DBF /* batch_norm_31.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D832142748D00C69DBF /* batch_norm_31.b_0 */; };
C2C08E5D2142748D00C69DBF /* conv2d_29.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D842142748D00C69DBF /* conv2d_29.w_0 */; };
C2C08E5E2142748D00C69DBF /* batch_norm_25.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D852142748D00C69DBF /* batch_norm_25.b_0 */; };
C2C08E5F2142748D00C69DBF /* conv2d_15.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D862142748D00C69DBF /* conv2d_15.w_0 */; };
C2C08E602142748D00C69DBF /* batch_norm_19.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D872142748D00C69DBF /* batch_norm_19.b_0 */; };
C2C08E612142748D00C69DBF /* batch_norm_16.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D882142748D00C69DBF /* batch_norm_16.w_2 */; };
C2C08E622142748D00C69DBF /* __model__ in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D892142748D00C69DBF /* __model__ */; };
C2C08E632142748D00C69DBF /* batch_norm_7.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D8A2142748D00C69DBF /* batch_norm_7.w_1 */; };
C2C08E642142748D00C69DBF /* batch_norm_6.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D8B2142748D00C69DBF /* batch_norm_6.w_1 */; };
C2C08E652142748D00C69DBF /* batch_norm_17.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D8C2142748D00C69DBF /* batch_norm_17.w_2 */; };
C2C08E662142748D00C69DBF /* conv2d_14.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D8D2142748D00C69DBF /* conv2d_14.w_0 */; };
C2C08E672142748D00C69DBF /* batch_norm_18.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D8E2142748D00C69DBF /* batch_norm_18.b_0 */; };
C2C08E682142748D00C69DBF /* conv2d_28.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D8F2142748D00C69DBF /* conv2d_28.w_0 */; };
C2C08E692142748D00C69DBF /* batch_norm_24.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D902142748D00C69DBF /* batch_norm_24.b_0 */; };
C2C08E6A2142748D00C69DBF /* batch_norm_30.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D912142748D00C69DBF /* batch_norm_30.b_0 */; };
C2C08E6B2142748D00C69DBF /* depthwise_conv2d_8.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D922142748D00C69DBF /* depthwise_conv2d_8.w_0 */; };
C2C08E6C2142748D00C69DBF /* batch_norm_5.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D932142748D00C69DBF /* batch_norm_5.w_0 */; };
C2C08E6D2142748D00C69DBF /* batch_norm_1.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D942142748D00C69DBF /* batch_norm_1.w_0 */; };
C2C08E6E2142748D00C69DBF /* conv2d_10.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D952142748D00C69DBF /* conv2d_10.w_0 */; };
C2C08E6F2142748D00C69DBF /* batch_norm_34.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D962142748D00C69DBF /* batch_norm_34.b_0 */; };
C2C08E702142748D00C69DBF /* batch_norm_20.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D972142748D00C69DBF /* batch_norm_20.b_0 */; };
C2C08E712142748D00C69DBF /* batch_norm_13.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D982142748D00C69DBF /* batch_norm_13.w_2 */; };
C2C08E722142748D00C69DBF /* batch_norm_2.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D992142748D00C69DBF /* batch_norm_2.w_1 */; };
C2C08E732142748D00C69DBF /* batch_norm_3.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D9A2142748D00C69DBF /* batch_norm_3.w_1 */; };
C2C08E742142748D00C69DBF /* batch_norm_12.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D9B2142748D00C69DBF /* batch_norm_12.w_2 */; };
C2C08E752142748D00C69DBF /* batch_norm_21.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D9C2142748D00C69DBF /* batch_norm_21.b_0 */; };
C2C08E762142748D00C69DBF /* conv2d_11.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D9D2142748D00C69DBF /* conv2d_11.w_0 */; };
C2C08E772142748D00C69DBF /* batch_norm_0.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D9E2142748D00C69DBF /* batch_norm_0.w_0 */; };
C2C08E782142748D00C69DBF /* batch_norm_2.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08D9F2142748D00C69DBF /* batch_norm_2.w_0 */; };
C2C08E792142748D00C69DBF /* conv2d_13.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA02142748D00C69DBF /* conv2d_13.w_0 */; };
C2C08E7A2142748D00C69DBF /* batch_norm_23.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA12142748D00C69DBF /* batch_norm_23.b_0 */; };
C2C08E7B2142748D00C69DBF /* batch_norm_10.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA22142748D00C69DBF /* batch_norm_10.w_2 */; };
C2C08E7C2142748D00C69DBF /* batch_norm_1.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA32142748D00C69DBF /* batch_norm_1.w_1 */; };
C2C08E7D2142748D00C69DBF /* batch_norm_0.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA42142748D00C69DBF /* batch_norm_0.w_1 */; };
C2C08E7E2142748D00C69DBF /* batch_norm_11.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA52142748D00C69DBF /* batch_norm_11.w_2 */; };
C2C08E7F2142748D00C69DBF /* batch_norm_22.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA62142748D00C69DBF /* batch_norm_22.b_0 */; };
C2C08E802142748D00C69DBF /* conv2d_12.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA72142748D00C69DBF /* conv2d_12.w_0 */; };
C2C08E812142748D00C69DBF /* batch_norm_3.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA82142748D00C69DBF /* batch_norm_3.w_0 */; };
C2C08E822142748D00C69DBF /* batch_norm_21.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DA92142748D00C69DBF /* batch_norm_21.w_1 */; };
C2C08E832142748D00C69DBF /* batch_norm_3.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DAA2142748D00C69DBF /* batch_norm_3.b_0 */; };
C2C08E842142748D00C69DBF /* batch_norm_22.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DAB2142748D00C69DBF /* batch_norm_22.w_0 */; };
C2C08E852142748D00C69DBF /* batch_norm_23.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DAC2142748D00C69DBF /* batch_norm_23.w_0 */; };
C2C08E862142748D00C69DBF /* batch_norm_2.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DAD2142748D00C69DBF /* batch_norm_2.b_0 */; };
C2C08E872142748D00C69DBF /* batch_norm_20.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DAE2142748D00C69DBF /* batch_norm_20.w_1 */; };
C2C08E882142748D00C69DBF /* batch_norm_34.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DAF2142748D00C69DBF /* batch_norm_34.w_1 */; };
C2C08E892142748D00C69DBF /* batch_norm_22.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB02142748D00C69DBF /* batch_norm_22.w_1 */; };
C2C08E8A2142748D00C69DBF /* batch_norm_0.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB12142748D00C69DBF /* batch_norm_0.b_0 */; };
C2C08E8B2142748D00C69DBF /* batch_norm_21.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB22142748D00C69DBF /* batch_norm_21.w_0 */; };
C2C08E8C2142748D00C69DBF /* batch_norm_20.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB32142748D00C69DBF /* batch_norm_20.w_0 */; };
C2C08E8D2142748D00C69DBF /* batch_norm_34.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB42142748D00C69DBF /* batch_norm_34.w_0 */; };
C2C08E8E2142748D00C69DBF /* batch_norm_1.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB52142748D00C69DBF /* batch_norm_1.b_0 */; };
C2C08E8F2142748D00C69DBF /* batch_norm_23.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB62142748D00C69DBF /* batch_norm_23.w_1 */; };
C2C08E902142748D00C69DBF /* batch_norm_27.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB72142748D00C69DBF /* batch_norm_27.w_1 */; };
C2C08E912142748D00C69DBF /* batch_norm_33.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB82142748D00C69DBF /* batch_norm_33.w_1 */; };
C2C08E922142748D00C69DBF /* batch_norm_5.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DB92142748D00C69DBF /* batch_norm_5.b_0 */; };
C2C08E932142748D00C69DBF /* batch_norm_18.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DBA2142748D00C69DBF /* batch_norm_18.w_0 */; };
C2C08E942142748D00C69DBF /* batch_norm_30.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DBB2142748D00C69DBF /* batch_norm_30.w_0 */; };
C2C08E952142748D00C69DBF /* batch_norm_24.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DBC2142748D00C69DBF /* batch_norm_24.w_0 */; };
C2C08E962142748D00C69DBF /* conv2d_28.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DBD2142748D00C69DBF /* conv2d_28.b_0 */; };
C2C08E972142748D00C69DBF /* batch_norm_25.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DBE2142748D00C69DBF /* batch_norm_25.w_0 */; };
C2C08E982142748D00C69DBF /* conv2d_29.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DBF2142748D00C69DBF /* conv2d_29.b_0 */; };
C2C08E992142748D00C69DBF /* batch_norm_31.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC02142748D00C69DBF /* batch_norm_31.w_0 */; };
C2C08E9A2142748D00C69DBF /* batch_norm_19.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC12142748D00C69DBF /* batch_norm_19.w_0 */; };
C2C08E9B2142748D00C69DBF /* batch_norm_4.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC22142748D00C69DBF /* batch_norm_4.b_0 */; };
C2C08E9C2142748D00C69DBF /* batch_norm_32.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC32142748D00C69DBF /* batch_norm_32.w_1 */; };
C2C08E9D2142748D00C69DBF /* batch_norm_26.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC42142748D00C69DBF /* batch_norm_26.w_1 */; };
C2C08E9E2142748D00C69DBF /* batch_norm_30.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC52142748D00C69DBF /* batch_norm_30.w_1 */; };
C2C08E9F2142748D00C69DBF /* batch_norm_24.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC62142748D00C69DBF /* batch_norm_24.w_1 */; };
C2C08EA02142748D00C69DBF /* batch_norm_18.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC72142748D00C69DBF /* batch_norm_18.w_1 */; };
C2C08EA12142748D00C69DBF /* batch_norm_6.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC82142748D00C69DBF /* batch_norm_6.b_0 */; };
C2C08EA22142748D00C69DBF /* batch_norm_9.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DC92142748D00C69DBF /* batch_norm_9.w_2 */; };
C2C08EA32142748D00C69DBF /* conv2d_8.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DCA2142748D00C69DBF /* conv2d_8.w_0 */; };
C2C08EA42142748D00C69DBF /* batch_norm_27.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DCB2142748D00C69DBF /* batch_norm_27.w_0 */; };
C2C08EA52142748D00C69DBF /* batch_norm_33.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DCC2142748D00C69DBF /* batch_norm_33.w_0 */; };
C2C08EA62142748D00C69DBF /* batch_norm_32.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DCD2142748D00C69DBF /* batch_norm_32.w_0 */; };
C2C08EA72142748D00C69DBF /* conv2d_9.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DCE2142748D00C69DBF /* conv2d_9.w_0 */; };
C2C08EA82142748D00C69DBF /* batch_norm_26.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DCF2142748D00C69DBF /* batch_norm_26.w_0 */; };
C2C08EA92142748D00C69DBF /* batch_norm_8.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD02142748D00C69DBF /* batch_norm_8.w_2 */; };
C2C08EAA2142748D00C69DBF /* batch_norm_7.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD12142748D00C69DBF /* batch_norm_7.b_0 */; };
C2C08EAB2142748D00C69DBF /* batch_norm_19.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD22142748D00C69DBF /* batch_norm_19.w_1 */; };
C2C08EAC2142748D00C69DBF /* batch_norm_25.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD32142748D00C69DBF /* batch_norm_25.w_1 */; };
C2C08EAD2142748D00C69DBF /* batch_norm_31.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD42142748D00C69DBF /* batch_norm_31.w_1 */; };
C2C08EAE2142748D00C69DBF /* batch_norm_28.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD52142748D00C69DBF /* batch_norm_28.w_1 */; };
C2C08EAF2142748D00C69DBF /* batch_norm_14.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD62142748D00C69DBF /* batch_norm_14.w_1 */; };
C2C08EB02142748D00C69DBF /* batch_norm_5.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD72142748D00C69DBF /* batch_norm_5.w_2 */; };
C2C08EB12142748D00C69DBF /* batch_norm_17.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD82142748D00C69DBF /* batch_norm_17.w_0 */; };
C2C08EB22142748D00C69DBF /* conv2d_33.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DD92142748D00C69DBF /* conv2d_33.b_0 */; };
C2C08EB32142748D00C69DBF /* conv2d_27.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DDA2142748D00C69DBF /* conv2d_27.b_0 */; };
C2C08EB42142748D00C69DBF /* conv2d_4.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DDB2142748D00C69DBF /* conv2d_4.w_0 */; };
C2C08EB52142748D00C69DBF /* conv2d_5.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DDC2142748D00C69DBF /* conv2d_5.w_0 */; };
C2C08EB62142748D00C69DBF /* conv2d_26.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DDD2142748D00C69DBF /* conv2d_26.b_0 */; };
C2C08EB72142748D00C69DBF /* conv2d_32.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DDE2142748D00C69DBF /* conv2d_32.b_0 */; };
C2C08EB82142748D00C69DBF /* batch_norm_16.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DDF2142748D00C69DBF /* batch_norm_16.w_0 */; };
C2C08EB92142748D00C69DBF /* batch_norm_4.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE02142748D00C69DBF /* batch_norm_4.w_2 */; };
C2C08EBA2142748D00C69DBF /* batch_norm_15.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE12142748D00C69DBF /* batch_norm_15.w_1 */; };
C2C08EBB2142748D00C69DBF /* batch_norm_29.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE22142748D00C69DBF /* batch_norm_29.w_1 */; };
C2C08EBC2142748D00C69DBF /* batch_norm_17.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE32142748D00C69DBF /* batch_norm_17.w_1 */; };
C2C08EBD2142748D00C69DBF /* batch_norm_9.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE42142748D00C69DBF /* batch_norm_9.b_0 */; };
C2C08EBE2142748D00C69DBF /* batch_norm_6.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE52142748D00C69DBF /* batch_norm_6.w_2 */; };
C2C08EBF2142748D00C69DBF /* batch_norm_14.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE62142748D00C69DBF /* batch_norm_14.w_0 */; };
C2C08EC02142748D00C69DBF /* batch_norm_28.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE72142748D00C69DBF /* batch_norm_28.w_0 */; };
C2C08EC12142748D00C69DBF /* conv2d_24.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE82142748D00C69DBF /* conv2d_24.b_0 */; };
C2C08EC22142748D00C69DBF /* conv2d_7.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DE92142748D00C69DBF /* conv2d_7.w_0 */; };
C2C08EC32142748D00C69DBF /* conv2d_30.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DEA2142748D00C69DBF /* conv2d_30.b_0 */; };
C2C08EC42142748D00C69DBF /* conv2d_31.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DEB2142748D00C69DBF /* conv2d_31.b_0 */; };
C2C08EC52142748D00C69DBF /* batch_norm_29.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DEC2142748D00C69DBF /* batch_norm_29.w_0 */; };
C2C08EC62142748D00C69DBF /* conv2d_6.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DED2142748D00C69DBF /* conv2d_6.w_0 */; };
C2C08EC72142748D00C69DBF /* conv2d_25.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DEE2142748D00C69DBF /* conv2d_25.b_0 */; };
C2C08EC82142748D00C69DBF /* batch_norm_15.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DEF2142748D00C69DBF /* batch_norm_15.w_0 */; };
C2C08EC92142748D00C69DBF /* batch_norm_7.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF02142748D00C69DBF /* batch_norm_7.w_2 */; };
C2C08ECA2142748D00C69DBF /* batch_norm_8.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF12142748D00C69DBF /* batch_norm_8.b_0 */; };
C2C08ECB2142748D00C69DBF /* batch_norm_16.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF22142748D00C69DBF /* batch_norm_16.w_1 */; };
C2C08ECC2142748D00C69DBF /* batch_norm_12.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF32142748D00C69DBF /* batch_norm_12.w_1 */; };
C2C08ECD2142748D00C69DBF /* batch_norm_3.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF42142748D00C69DBF /* batch_norm_3.w_2 */; };
C2C08ECE2142748D00C69DBF /* conv2d_2.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF52142748D00C69DBF /* conv2d_2.w_0 */; };
C2C08ECF2142748D00C69DBF /* batch_norm_11.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF62142748D00C69DBF /* batch_norm_11.w_0 */; };
C2C08ED02142748D00C69DBF /* batch_norm_10.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF72142748D00C69DBF /* batch_norm_10.w_0 */; };
C2C08ED12142748D00C69DBF /* conv2d_3.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF82142748D00C69DBF /* conv2d_3.w_0 */; };
C2C08ED22142748D00C69DBF /* batch_norm_2.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DF92142748D00C69DBF /* batch_norm_2.w_2 */; };
C2C08ED32142748D00C69DBF /* depthwise_conv2d_12.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DFA2142748D00C69DBF /* depthwise_conv2d_12.w_0 */; };
C2C08ED42142748D00C69DBF /* batch_norm_13.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DFB2142748D00C69DBF /* batch_norm_13.w_1 */; };
C2C08ED52142748D00C69DBF /* batch_norm_11.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DFC2142748D00C69DBF /* batch_norm_11.w_1 */; };
C2C08ED62142748D00C69DBF /* depthwise_conv2d_10.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DFD2142748D00C69DBF /* depthwise_conv2d_10.w_0 */; };
C2C08ED72142748D00C69DBF /* batch_norm_0.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DFE2142748D00C69DBF /* batch_norm_0.w_2 */; };
C2C08ED82142748D00C69DBF /* conv2d_22.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08DFF2142748D00C69DBF /* conv2d_22.b_0 */; };
C2C08ED92142748D00C69DBF /* conv2d_1.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E002142748D00C69DBF /* conv2d_1.w_0 */; };
C2C08EDA2142748D00C69DBF /* batch_norm_12.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E012142748D00C69DBF /* batch_norm_12.w_0 */; };
C2C08EDB2142748D00C69DBF /* batch_norm_13.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E022142748D00C69DBF /* batch_norm_13.w_0 */; };
C2C08EDC2142748D00C69DBF /* conv2d_0.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E032142748D00C69DBF /* conv2d_0.w_0 */; };
C2C08EDD2142748D00C69DBF /* conv2d_23.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E042142748D00C69DBF /* conv2d_23.b_0 */; };
C2C08EDE2142748D00C69DBF /* batch_norm_1.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E052142748D00C69DBF /* batch_norm_1.w_2 */; };
C2C08EDF2142748D00C69DBF /* batch_norm_10.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E062142748D00C69DBF /* batch_norm_10.w_1 */; };
C2C08EE02142748D00C69DBF /* depthwise_conv2d_11.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E072142748D00C69DBF /* depthwise_conv2d_11.w_0 */; };
C2C08EE12142748D00C69DBF /* depthwise_conv2d_3.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E082142748D00C69DBF /* depthwise_conv2d_3.w_0 */; };
C2C08EE22142748D00C69DBF /* batch_norm_13.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E092142748D00C69DBF /* batch_norm_13.b_0 */; };
C2C08EE32142748D00C69DBF /* conv2d_23.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E0A2142748D00C69DBF /* conv2d_23.w_0 */; };
C2C08EE42142748D00C69DBF /* batch_norm_20.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E0B2142748D00C69DBF /* batch_norm_20.w_2 */; };
C2C08EE52142748D00C69DBF /* batch_norm_34.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E0C2142748D00C69DBF /* batch_norm_34.w_2 */; };
C2C08EE62142748D00C69DBF /* batch_norm_21.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E0D2142748D00C69DBF /* batch_norm_21.w_2 */; };
C2C08EE72142748D00C69DBF /* conv2d_22.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E0E2142748D00C69DBF /* conv2d_22.w_0 */; };
C2C08EE82142748D00C69DBF /* batch_norm_12.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E0F2142748D00C69DBF /* batch_norm_12.b_0 */; };
C2C08EE92142748D00C69DBF /* depthwise_conv2d_2.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E102142748D00C69DBF /* depthwise_conv2d_2.w_0 */; };
C2C08EEA2142748D00C69DBF /* depthwise_conv2d_0.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E112142748D00C69DBF /* depthwise_conv2d_0.w_0 */; };
C2C08EEB2142748D00C69DBF /* batch_norm_10.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E122142748D00C69DBF /* batch_norm_10.b_0 */; };
C2C08EEC2142748D00C69DBF /* conv2d_20.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E132142748D00C69DBF /* conv2d_20.w_0 */; };
C2C08EED2142748D00C69DBF /* batch_norm_23.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E142142748D00C69DBF /* batch_norm_23.w_2 */; };
C2C08EEE2142748D00C69DBF /* batch_norm_22.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E152142748D00C69DBF /* batch_norm_22.w_2 */; };
C2C08EEF2142748D00C69DBF /* conv2d_21.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E162142748D00C69DBF /* conv2d_21.w_0 */; };
C2C08EF02142748D00C69DBF /* batch_norm_11.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E172142748D00C69DBF /* batch_norm_11.b_0 */; };
C2C08EF12142748D00C69DBF /* depthwise_conv2d_1.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E182142748D00C69DBF /* depthwise_conv2d_1.w_0 */; };
C2C08EF22142748D00C69DBF /* depthwise_conv2d_5.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E192142748D00C69DBF /* depthwise_conv2d_5.w_0 */; };
C2C08EF32142748D00C69DBF /* batch_norm_8.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E1A2142748D00C69DBF /* batch_norm_8.w_0 */; };
C2C08EF42142748D00C69DBF /* conv2d_25.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E1B2142748D00C69DBF /* conv2d_25.w_0 */; };
C2C08EF52142748D00C69DBF /* batch_norm_29.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E1C2142748D00C69DBF /* batch_norm_29.b_0 */; };
C2C08EF62142748D00C69DBF /* conv2d_31.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E1D2142748D00C69DBF /* conv2d_31.w_0 */; };
C2C08EF72142748D00C69DBF /* conv2d_19.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E1E2142748D00C69DBF /* conv2d_19.w_0 */; };
C2C08EF82142748D00C69DBF /* batch_norm_15.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E1F2142748D00C69DBF /* batch_norm_15.b_0 */; };
C2C08EF92142748D00C69DBF /* batch_norm_32.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E202142748D00C69DBF /* batch_norm_32.w_2 */; };
C2C08EFA2142748D00C69DBF /* batch_norm_26.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E212142748D00C69DBF /* batch_norm_26.w_2 */; };
C2C08EFB2142748D00C69DBF /* batch_norm_27.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E222142748D00C69DBF /* batch_norm_27.w_2 */; };
C2C08EFC2142748D00C69DBF /* batch_norm_33.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E232142748D00C69DBF /* batch_norm_33.w_2 */; };
C2C08EFD2142748D00C69DBF /* conv2d_18.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E242142748D00C69DBF /* conv2d_18.w_0 */; };
C2C08EFE2142748D00C69DBF /* batch_norm_14.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E252142748D00C69DBF /* batch_norm_14.b_0 */; };
C2C08EFF2142748D00C69DBF /* conv2d_30.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E262142748D00C69DBF /* conv2d_30.w_0 */; };
C2C08F002142748D00C69DBF /* conv2d_24.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E272142748D00C69DBF /* conv2d_24.w_0 */; };
C2C08F012142748D00C69DBF /* batch_norm_28.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E282142748D00C69DBF /* batch_norm_28.b_0 */; };
C2C08F022142748D00C69DBF /* batch_norm_9.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E292142748D00C69DBF /* batch_norm_9.w_0 */; };
C2C08F032142748D00C69DBF /* depthwise_conv2d_4.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E2A2142748D00C69DBF /* depthwise_conv2d_4.w_0 */; };
C2C08F042142748D00C69DBF /* depthwise_conv2d_6.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E2B2142748D00C69DBF /* depthwise_conv2d_6.w_0 */; };
C2C08F052142748D00C69DBF /* conv2d_32.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E2C2142748D00C69DBF /* conv2d_32.w_0 */; };
C2C08F062142748D00C69DBF /* conv2d_26.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E2D2142748D00C69DBF /* conv2d_26.w_0 */; };
C2C08F072142748D00C69DBF /* batch_norm_16.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E2E2142748D00C69DBF /* batch_norm_16.b_0 */; };
C2C08F082142748D00C69DBF /* batch_norm_19.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E2F2142748D00C69DBF /* batch_norm_19.w_2 */; };
C2C08F092142748D00C69DBF /* batch_norm_25.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E302142748D00C69DBF /* batch_norm_25.w_2 */; };
C2C08F0A2142748D00C69DBF /* batch_norm_31.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E312142748D00C69DBF /* batch_norm_31.w_2 */; };
C2C08F0B2142748D00C69DBF /* batch_norm_8.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E322142748D00C69DBF /* batch_norm_8.w_1 */; };
C2C08F0C2142748D00C69DBF /* batch_norm_9.w_1 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E332142748D00C69DBF /* batch_norm_9.w_1 */; };
C2C08F0D2142748D00C69DBF /* batch_norm_30.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E342142748D00C69DBF /* batch_norm_30.w_2 */; };
C2C08F0E2142748D00C69DBF /* batch_norm_24.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E352142748D00C69DBF /* batch_norm_24.w_2 */; };
C2C08F0F2142748D00C69DBF /* batch_norm_18.w_2 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E362142748D00C69DBF /* batch_norm_18.w_2 */; };
C2C08F102142748D00C69DBF /* batch_norm_17.b_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E372142748D00C69DBF /* batch_norm_17.b_0 */; };
C2C08F112142748D00C69DBF /* conv2d_27.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E382142748D00C69DBF /* conv2d_27.w_0 */; };
C2C08F122142748D00C69DBF /* conv2d_33.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E392142748D00C69DBF /* conv2d_33.w_0 */; };
C2C08F132142748D00C69DBF /* depthwise_conv2d_7.w_0 in Resources */ = {isa = PBXBuildFile; fileRef = C2C08E3A2142748D00C69DBF /* depthwise_conv2d_7.w_0 */; };
FC013928210204A3008100E3 /* PreProcessKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FC013927210204A3008100E3 /* PreProcessKernel.metal */; }; FC013928210204A3008100E3 /* PreProcessKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FC013927210204A3008100E3 /* PreProcessKernel.metal */; };
FC039B8220E11C550081E9F8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC039B8120E11C550081E9F8 /* AppDelegate.swift */; }; FC039B8220E11C550081E9F8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC039B8120E11C550081E9F8 /* AppDelegate.swift */; };
FC039B8420E11C550081E9F8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC039B8320E11C550081E9F8 /* ViewController.swift */; }; FC039B8420E11C550081E9F8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC039B8320E11C550081E9F8 /* ViewController.swift */; };
FC039B8720E11C550081E9F8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8520E11C550081E9F8 /* Main.storyboard */; }; FC039B8720E11C550081E9F8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8520E11C550081E9F8 /* Main.storyboard */; };
FC039B8920E11C560081E9F8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8820E11C560081E9F8 /* Assets.xcassets */; }; FC039B8920E11C560081E9F8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8820E11C560081E9F8 /* Assets.xcassets */; };
FC039B8C20E11C560081E9F8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8A20E11C560081E9F8 /* LaunchScreen.storyboard */; }; FC039B8C20E11C560081E9F8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC039B8A20E11C560081E9F8 /* LaunchScreen.storyboard */; };
FC803BCD214D27930094B8E5 /* FPSCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC803BCB214D27920094B8E5 /* FPSCounter.swift */; };
FC803BCE214D27930094B8E5 /* VideoCapture.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC803BCC214D27920094B8E5 /* VideoCapture.swift */; };
FC8CFEE62135452C0094D569 /* genet_params in Resources */ = {isa = PBXBuildFile; fileRef = FC8CFEE42135452B0094D569 /* genet_params */; };
FC8CFEE72135452C0094D569 /* genet_model in Resources */ = {isa = PBXBuildFile; fileRef = FC8CFEE52135452B0094D569 /* genet_model */; };
FC8CFEF8213551D10094D569 /* params in Resources */ = {isa = PBXBuildFile; fileRef = FC8CFEF6213551D00094D569 /* params */; };
FC8CFEF9213551D10094D569 /* model in Resources */ = {isa = PBXBuildFile; fileRef = FC8CFEF7213551D00094D569 /* model */; };
FC918191211DBC3500B6F354 /* paddle-mobile.png in Resources */ = {isa = PBXBuildFile; fileRef = FC918190211DBC3500B6F354 /* paddle-mobile.png */; };
FC918193211DC70500B6F354 /* iphone.JPG in Resources */ = {isa = PBXBuildFile; fileRef = FC918192211DC70500B6F354 /* iphone.JPG */; };
FC9A19E72148C38400CD9CBF /* ar_model in Resources */ = {isa = PBXBuildFile; fileRef = FC9A19E52148C38400CD9CBF /* ar_model */; };
FC9A19E82148C38400CD9CBF /* ar_params in Resources */ = {isa = PBXBuildFile; fileRef = FC9A19E62148C38400CD9CBF /* ar_params */; };
FCA3A16121313E1F00084FE5 /* hand.jpg in Resources */ = {isa = PBXBuildFile; fileRef = FCA3A16021313E1F00084FE5 /* hand.jpg */; };
FCBCCC522122EEDC00D94F7E /* ssd_hand_params in Resources */ = {isa = PBXBuildFile; fileRef = FCBCCC502122EEDC00D94F7E /* ssd_hand_params */; };
FCBCCC532122EEDC00D94F7E /* ssd_hand_model in Resources */ = {isa = PBXBuildFile; fileRef = FCBCCC512122EEDC00D94F7E /* ssd_hand_model */; };
FCBCCC552122EF5500D94F7E /* MetalHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCBCCC542122EF5400D94F7E /* MetalHelper.swift */; }; FCBCCC552122EF5500D94F7E /* MetalHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCBCCC542122EF5400D94F7E /* MetalHelper.swift */; };
FCDFD41B211D91C7005AB38B /* synset.txt in Resources */ = {isa = PBXBuildFile; fileRef = FCDFD41A211D91C7005AB38B /* synset.txt */; };
FCEBEC2C20E1391F00C0B14D /* paddle_mobile.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */; }; FCEBEC2C20E1391F00C0B14D /* paddle_mobile.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */; };
FCEBEC2D20E1391F00C0B14D /* paddle_mobile.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; FCEBEC2D20E1391F00C0B14D /* paddle_mobile.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
FCEEE7D4210627A000444BEC /* banana.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = FCEEE7D3210627A000444BEC /* banana.jpeg */; };
FCF437E8214B6DDB00943429 /* MultiPredictViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF437E7214B6DDB00943429 /* MultiPredictViewController.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
...@@ -256,225 +53,6 @@ ...@@ -256,225 +53,6 @@
081C9CF10DB06C58B8B6B039 /* Pods-paddle-mobile-demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-paddle-mobile-demo.release.xcconfig"; path = "../Pods/Target Support Files/Pods-paddle-mobile-demo/Pods-paddle-mobile-demo.release.xcconfig"; sourceTree = "<group>"; }; 081C9CF10DB06C58B8B6B039 /* Pods-paddle-mobile-demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-paddle-mobile-demo.release.xcconfig"; path = "../Pods/Target Support Files/Pods-paddle-mobile-demo/Pods-paddle-mobile-demo.release.xcconfig"; sourceTree = "<group>"; };
18896810981724F8A0FED62A /* Pods_paddle_mobile_demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_paddle_mobile_demo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 18896810981724F8A0FED62A /* Pods_paddle_mobile_demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_paddle_mobile_demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
878829884E1A14D7044721D5 /* Pods-paddle-mobile-demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-paddle-mobile-demo.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-paddle-mobile-demo/Pods-paddle-mobile-demo.debug.xcconfig"; sourceTree = "<group>"; }; 878829884E1A14D7044721D5 /* Pods-paddle-mobile-demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-paddle-mobile-demo.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-paddle-mobile-demo/Pods-paddle-mobile-demo.debug.xcconfig"; sourceTree = "<group>"; };
C23717862148E5A50092444E /* ar_model */ = {isa = PBXFileReference; lastKnownFileType = file; path = ar_model; sourceTree = "<group>"; };
C23717872148E5A50092444E /* ar_params */ = {isa = PBXFileReference; lastKnownFileType = file; path = ar_params; sourceTree = "<group>"; };
C2C08D5B2142748D00C69DBF /* synset.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = synset.txt; sourceTree = "<group>"; };
C2C08D5C2142748D00C69DBF /* banana.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = banana.jpeg; sourceTree = "<group>"; };
C2C08D5D2142748D00C69DBF /* hand.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hand.jpg; sourceTree = "<group>"; };
C2C08D5E2142748D00C69DBF /* iphone.JPG */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = iphone.JPG; sourceTree = "<group>"; };
C2C08D5F2142748D00C69DBF /* paddle-mobile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "paddle-mobile.png"; sourceTree = "<group>"; };
C2C08D622142748D00C69DBF /* params */ = {isa = PBXFileReference; lastKnownFileType = file; path = params; sourceTree = "<group>"; };
C2C08D632142748D00C69DBF /* model */ = {isa = PBXFileReference; lastKnownFileType = file; path = model; sourceTree = "<group>"; };
C2C08D652142748D00C69DBF /* genet_params */ = {isa = PBXFileReference; lastKnownFileType = file; path = genet_params; sourceTree = "<group>"; };
C2C08D662142748D00C69DBF /* genet_model */ = {isa = PBXFileReference; lastKnownFileType = file; path = genet_model; sourceTree = "<group>"; };
C2C08D682142748D00C69DBF /* ssd_hand_params */ = {isa = PBXFileReference; lastKnownFileType = file; path = ssd_hand_params; sourceTree = "<group>"; };
C2C08D692142748D00C69DBF /* ssd_hand_model */ = {isa = PBXFileReference; lastKnownFileType = file; path = ssd_hand_model; sourceTree = "<group>"; };
C2C08D6B2142748D00C69DBF /* mobilenet */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mobilenet; sourceTree = "<group>"; };
C2C08D6C2142748D00C69DBF /* params */ = {isa = PBXFileReference; lastKnownFileType = file; path = params; sourceTree = "<group>"; };
C2C08D6D2142748D00C69DBF /* model */ = {isa = PBXFileReference; lastKnownFileType = file; path = model; sourceTree = "<group>"; };
C2C08D6E2142748D00C69DBF /* yolo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yolo; sourceTree = "<group>"; };
C2C08D702142748D00C69DBF /* params */ = {isa = PBXFileReference; lastKnownFileType = file; path = params; sourceTree = "<group>"; };
C2C08D712142748D00C69DBF /* model */ = {isa = PBXFileReference; lastKnownFileType = file; path = model; sourceTree = "<group>"; };
C2C08D732142748D00C69DBF /* batch_norm_7.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_7.w_0; sourceTree = "<group>"; };
C2C08D742142748D00C69DBF /* batch_norm_26.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_26.b_0; sourceTree = "<group>"; };
C2C08D752142748D00C69DBF /* batch_norm_32.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_32.b_0; sourceTree = "<group>"; };
C2C08D762142748D00C69DBF /* conv2d_16.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_16.w_0; sourceTree = "<group>"; };
C2C08D772142748D00C69DBF /* batch_norm_15.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_15.w_2; sourceTree = "<group>"; };
C2C08D782142748D00C69DBF /* batch_norm_29.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_29.w_2; sourceTree = "<group>"; };
C2C08D792142748D00C69DBF /* batch_norm_4.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_4.w_1; sourceTree = "<group>"; };
C2C08D7A2142748D00C69DBF /* batch_norm_5.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_5.w_1; sourceTree = "<group>"; };
C2C08D7B2142748D00C69DBF /* batch_norm_28.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_28.w_2; sourceTree = "<group>"; };
C2C08D7C2142748D00C69DBF /* batch_norm_14.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_14.w_2; sourceTree = "<group>"; };
C2C08D7D2142748D00C69DBF /* conv2d_17.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_17.w_0; sourceTree = "<group>"; };
C2C08D7E2142748D00C69DBF /* batch_norm_33.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_33.b_0; sourceTree = "<group>"; };
C2C08D7F2142748D00C69DBF /* batch_norm_27.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_27.b_0; sourceTree = "<group>"; };
C2C08D802142748D00C69DBF /* batch_norm_6.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_6.w_0; sourceTree = "<group>"; };
C2C08D812142748D00C69DBF /* batch_norm_4.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_4.w_0; sourceTree = "<group>"; };
C2C08D822142748D00C69DBF /* depthwise_conv2d_9.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_9.w_0; sourceTree = "<group>"; };
C2C08D832142748D00C69DBF /* batch_norm_31.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_31.b_0; sourceTree = "<group>"; };
C2C08D842142748D00C69DBF /* conv2d_29.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_29.w_0; sourceTree = "<group>"; };
C2C08D852142748D00C69DBF /* batch_norm_25.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_25.b_0; sourceTree = "<group>"; };
C2C08D862142748D00C69DBF /* conv2d_15.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_15.w_0; sourceTree = "<group>"; };
C2C08D872142748D00C69DBF /* batch_norm_19.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_19.b_0; sourceTree = "<group>"; };
C2C08D882142748D00C69DBF /* batch_norm_16.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_16.w_2; sourceTree = "<group>"; };
C2C08D892142748D00C69DBF /* __model__ */ = {isa = PBXFileReference; lastKnownFileType = file; path = __model__; sourceTree = "<group>"; };
C2C08D8A2142748D00C69DBF /* batch_norm_7.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_7.w_1; sourceTree = "<group>"; };
C2C08D8B2142748D00C69DBF /* batch_norm_6.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_6.w_1; sourceTree = "<group>"; };
C2C08D8C2142748D00C69DBF /* batch_norm_17.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_17.w_2; sourceTree = "<group>"; };
C2C08D8D2142748D00C69DBF /* conv2d_14.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_14.w_0; sourceTree = "<group>"; };
C2C08D8E2142748D00C69DBF /* batch_norm_18.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_18.b_0; sourceTree = "<group>"; };
C2C08D8F2142748D00C69DBF /* conv2d_28.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_28.w_0; sourceTree = "<group>"; };
C2C08D902142748D00C69DBF /* batch_norm_24.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_24.b_0; sourceTree = "<group>"; };
C2C08D912142748D00C69DBF /* batch_norm_30.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_30.b_0; sourceTree = "<group>"; };
C2C08D922142748D00C69DBF /* depthwise_conv2d_8.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_8.w_0; sourceTree = "<group>"; };
C2C08D932142748D00C69DBF /* batch_norm_5.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_5.w_0; sourceTree = "<group>"; };
C2C08D942142748D00C69DBF /* batch_norm_1.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_1.w_0; sourceTree = "<group>"; };
C2C08D952142748D00C69DBF /* conv2d_10.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_10.w_0; sourceTree = "<group>"; };
C2C08D962142748D00C69DBF /* batch_norm_34.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_34.b_0; sourceTree = "<group>"; };
C2C08D972142748D00C69DBF /* batch_norm_20.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_20.b_0; sourceTree = "<group>"; };
C2C08D982142748D00C69DBF /* batch_norm_13.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_13.w_2; sourceTree = "<group>"; };
C2C08D992142748D00C69DBF /* batch_norm_2.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_2.w_1; sourceTree = "<group>"; };
C2C08D9A2142748D00C69DBF /* batch_norm_3.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_3.w_1; sourceTree = "<group>"; };
C2C08D9B2142748D00C69DBF /* batch_norm_12.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_12.w_2; sourceTree = "<group>"; };
C2C08D9C2142748D00C69DBF /* batch_norm_21.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_21.b_0; sourceTree = "<group>"; };
C2C08D9D2142748D00C69DBF /* conv2d_11.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_11.w_0; sourceTree = "<group>"; };
C2C08D9E2142748D00C69DBF /* batch_norm_0.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_0.w_0; sourceTree = "<group>"; };
C2C08D9F2142748D00C69DBF /* batch_norm_2.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_2.w_0; sourceTree = "<group>"; };
C2C08DA02142748D00C69DBF /* conv2d_13.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_13.w_0; sourceTree = "<group>"; };
C2C08DA12142748D00C69DBF /* batch_norm_23.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_23.b_0; sourceTree = "<group>"; };
C2C08DA22142748D00C69DBF /* batch_norm_10.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_10.w_2; sourceTree = "<group>"; };
C2C08DA32142748D00C69DBF /* batch_norm_1.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_1.w_1; sourceTree = "<group>"; };
C2C08DA42142748D00C69DBF /* batch_norm_0.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_0.w_1; sourceTree = "<group>"; };
C2C08DA52142748D00C69DBF /* batch_norm_11.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_11.w_2; sourceTree = "<group>"; };
C2C08DA62142748D00C69DBF /* batch_norm_22.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_22.b_0; sourceTree = "<group>"; };
C2C08DA72142748D00C69DBF /* conv2d_12.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_12.w_0; sourceTree = "<group>"; };
C2C08DA82142748D00C69DBF /* batch_norm_3.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_3.w_0; sourceTree = "<group>"; };
C2C08DA92142748D00C69DBF /* batch_norm_21.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_21.w_1; sourceTree = "<group>"; };
C2C08DAA2142748D00C69DBF /* batch_norm_3.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_3.b_0; sourceTree = "<group>"; };
C2C08DAB2142748D00C69DBF /* batch_norm_22.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_22.w_0; sourceTree = "<group>"; };
C2C08DAC2142748D00C69DBF /* batch_norm_23.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_23.w_0; sourceTree = "<group>"; };
C2C08DAD2142748D00C69DBF /* batch_norm_2.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_2.b_0; sourceTree = "<group>"; };
C2C08DAE2142748D00C69DBF /* batch_norm_20.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_20.w_1; sourceTree = "<group>"; };
C2C08DAF2142748D00C69DBF /* batch_norm_34.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_34.w_1; sourceTree = "<group>"; };
C2C08DB02142748D00C69DBF /* batch_norm_22.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_22.w_1; sourceTree = "<group>"; };
C2C08DB12142748D00C69DBF /* batch_norm_0.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_0.b_0; sourceTree = "<group>"; };
C2C08DB22142748D00C69DBF /* batch_norm_21.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_21.w_0; sourceTree = "<group>"; };
C2C08DB32142748D00C69DBF /* batch_norm_20.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_20.w_0; sourceTree = "<group>"; };
C2C08DB42142748D00C69DBF /* batch_norm_34.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_34.w_0; sourceTree = "<group>"; };
C2C08DB52142748D00C69DBF /* batch_norm_1.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_1.b_0; sourceTree = "<group>"; };
C2C08DB62142748D00C69DBF /* batch_norm_23.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_23.w_1; sourceTree = "<group>"; };
C2C08DB72142748D00C69DBF /* batch_norm_27.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_27.w_1; sourceTree = "<group>"; };
C2C08DB82142748D00C69DBF /* batch_norm_33.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_33.w_1; sourceTree = "<group>"; };
C2C08DB92142748D00C69DBF /* batch_norm_5.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_5.b_0; sourceTree = "<group>"; };
C2C08DBA2142748D00C69DBF /* batch_norm_18.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_18.w_0; sourceTree = "<group>"; };
C2C08DBB2142748D00C69DBF /* batch_norm_30.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_30.w_0; sourceTree = "<group>"; };
C2C08DBC2142748D00C69DBF /* batch_norm_24.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_24.w_0; sourceTree = "<group>"; };
C2C08DBD2142748D00C69DBF /* conv2d_28.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_28.b_0; sourceTree = "<group>"; };
C2C08DBE2142748D00C69DBF /* batch_norm_25.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_25.w_0; sourceTree = "<group>"; };
C2C08DBF2142748D00C69DBF /* conv2d_29.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_29.b_0; sourceTree = "<group>"; };
C2C08DC02142748D00C69DBF /* batch_norm_31.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_31.w_0; sourceTree = "<group>"; };
C2C08DC12142748D00C69DBF /* batch_norm_19.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_19.w_0; sourceTree = "<group>"; };
C2C08DC22142748D00C69DBF /* batch_norm_4.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_4.b_0; sourceTree = "<group>"; };
C2C08DC32142748D00C69DBF /* batch_norm_32.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_32.w_1; sourceTree = "<group>"; };
C2C08DC42142748D00C69DBF /* batch_norm_26.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_26.w_1; sourceTree = "<group>"; };
C2C08DC52142748D00C69DBF /* batch_norm_30.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_30.w_1; sourceTree = "<group>"; };
C2C08DC62142748D00C69DBF /* batch_norm_24.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_24.w_1; sourceTree = "<group>"; };
C2C08DC72142748D00C69DBF /* batch_norm_18.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_18.w_1; sourceTree = "<group>"; };
C2C08DC82142748D00C69DBF /* batch_norm_6.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_6.b_0; sourceTree = "<group>"; };
C2C08DC92142748D00C69DBF /* batch_norm_9.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_9.w_2; sourceTree = "<group>"; };
C2C08DCA2142748D00C69DBF /* conv2d_8.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_8.w_0; sourceTree = "<group>"; };
C2C08DCB2142748D00C69DBF /* batch_norm_27.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_27.w_0; sourceTree = "<group>"; };
C2C08DCC2142748D00C69DBF /* batch_norm_33.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_33.w_0; sourceTree = "<group>"; };
C2C08DCD2142748D00C69DBF /* batch_norm_32.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_32.w_0; sourceTree = "<group>"; };
C2C08DCE2142748D00C69DBF /* conv2d_9.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_9.w_0; sourceTree = "<group>"; };
C2C08DCF2142748D00C69DBF /* batch_norm_26.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_26.w_0; sourceTree = "<group>"; };
C2C08DD02142748D00C69DBF /* batch_norm_8.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_8.w_2; sourceTree = "<group>"; };
C2C08DD12142748D00C69DBF /* batch_norm_7.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_7.b_0; sourceTree = "<group>"; };
C2C08DD22142748D00C69DBF /* batch_norm_19.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_19.w_1; sourceTree = "<group>"; };
C2C08DD32142748D00C69DBF /* batch_norm_25.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_25.w_1; sourceTree = "<group>"; };
C2C08DD42142748D00C69DBF /* batch_norm_31.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_31.w_1; sourceTree = "<group>"; };
C2C08DD52142748D00C69DBF /* batch_norm_28.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_28.w_1; sourceTree = "<group>"; };
C2C08DD62142748D00C69DBF /* batch_norm_14.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_14.w_1; sourceTree = "<group>"; };
C2C08DD72142748D00C69DBF /* batch_norm_5.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_5.w_2; sourceTree = "<group>"; };
C2C08DD82142748D00C69DBF /* batch_norm_17.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_17.w_0; sourceTree = "<group>"; };
C2C08DD92142748D00C69DBF /* conv2d_33.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_33.b_0; sourceTree = "<group>"; };
C2C08DDA2142748D00C69DBF /* conv2d_27.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_27.b_0; sourceTree = "<group>"; };
C2C08DDB2142748D00C69DBF /* conv2d_4.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_4.w_0; sourceTree = "<group>"; };
C2C08DDC2142748D00C69DBF /* conv2d_5.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_5.w_0; sourceTree = "<group>"; };
C2C08DDD2142748D00C69DBF /* conv2d_26.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_26.b_0; sourceTree = "<group>"; };
C2C08DDE2142748D00C69DBF /* conv2d_32.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_32.b_0; sourceTree = "<group>"; };
C2C08DDF2142748D00C69DBF /* batch_norm_16.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_16.w_0; sourceTree = "<group>"; };
C2C08DE02142748D00C69DBF /* batch_norm_4.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_4.w_2; sourceTree = "<group>"; };
C2C08DE12142748D00C69DBF /* batch_norm_15.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_15.w_1; sourceTree = "<group>"; };
C2C08DE22142748D00C69DBF /* batch_norm_29.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_29.w_1; sourceTree = "<group>"; };
C2C08DE32142748D00C69DBF /* batch_norm_17.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_17.w_1; sourceTree = "<group>"; };
C2C08DE42142748D00C69DBF /* batch_norm_9.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_9.b_0; sourceTree = "<group>"; };
C2C08DE52142748D00C69DBF /* batch_norm_6.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_6.w_2; sourceTree = "<group>"; };
C2C08DE62142748D00C69DBF /* batch_norm_14.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_14.w_0; sourceTree = "<group>"; };
C2C08DE72142748D00C69DBF /* batch_norm_28.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_28.w_0; sourceTree = "<group>"; };
C2C08DE82142748D00C69DBF /* conv2d_24.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_24.b_0; sourceTree = "<group>"; };
C2C08DE92142748D00C69DBF /* conv2d_7.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_7.w_0; sourceTree = "<group>"; };
C2C08DEA2142748D00C69DBF /* conv2d_30.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_30.b_0; sourceTree = "<group>"; };
C2C08DEB2142748D00C69DBF /* conv2d_31.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_31.b_0; sourceTree = "<group>"; };
C2C08DEC2142748D00C69DBF /* batch_norm_29.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_29.w_0; sourceTree = "<group>"; };
C2C08DED2142748D00C69DBF /* conv2d_6.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_6.w_0; sourceTree = "<group>"; };
C2C08DEE2142748D00C69DBF /* conv2d_25.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_25.b_0; sourceTree = "<group>"; };
C2C08DEF2142748D00C69DBF /* batch_norm_15.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_15.w_0; sourceTree = "<group>"; };
C2C08DF02142748D00C69DBF /* batch_norm_7.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_7.w_2; sourceTree = "<group>"; };
C2C08DF12142748D00C69DBF /* batch_norm_8.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_8.b_0; sourceTree = "<group>"; };
C2C08DF22142748D00C69DBF /* batch_norm_16.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_16.w_1; sourceTree = "<group>"; };
C2C08DF32142748D00C69DBF /* batch_norm_12.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_12.w_1; sourceTree = "<group>"; };
C2C08DF42142748D00C69DBF /* batch_norm_3.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_3.w_2; sourceTree = "<group>"; };
C2C08DF52142748D00C69DBF /* conv2d_2.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_2.w_0; sourceTree = "<group>"; };
C2C08DF62142748D00C69DBF /* batch_norm_11.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_11.w_0; sourceTree = "<group>"; };
C2C08DF72142748D00C69DBF /* batch_norm_10.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_10.w_0; sourceTree = "<group>"; };
C2C08DF82142748D00C69DBF /* conv2d_3.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_3.w_0; sourceTree = "<group>"; };
C2C08DF92142748D00C69DBF /* batch_norm_2.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_2.w_2; sourceTree = "<group>"; };
C2C08DFA2142748D00C69DBF /* depthwise_conv2d_12.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_12.w_0; sourceTree = "<group>"; };
C2C08DFB2142748D00C69DBF /* batch_norm_13.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_13.w_1; sourceTree = "<group>"; };
C2C08DFC2142748D00C69DBF /* batch_norm_11.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_11.w_1; sourceTree = "<group>"; };
C2C08DFD2142748D00C69DBF /* depthwise_conv2d_10.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_10.w_0; sourceTree = "<group>"; };
C2C08DFE2142748D00C69DBF /* batch_norm_0.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_0.w_2; sourceTree = "<group>"; };
C2C08DFF2142748D00C69DBF /* conv2d_22.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_22.b_0; sourceTree = "<group>"; };
C2C08E002142748D00C69DBF /* conv2d_1.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_1.w_0; sourceTree = "<group>"; };
C2C08E012142748D00C69DBF /* batch_norm_12.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_12.w_0; sourceTree = "<group>"; };
C2C08E022142748D00C69DBF /* batch_norm_13.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_13.w_0; sourceTree = "<group>"; };
C2C08E032142748D00C69DBF /* conv2d_0.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_0.w_0; sourceTree = "<group>"; };
C2C08E042142748D00C69DBF /* conv2d_23.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_23.b_0; sourceTree = "<group>"; };
C2C08E052142748D00C69DBF /* batch_norm_1.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_1.w_2; sourceTree = "<group>"; };
C2C08E062142748D00C69DBF /* batch_norm_10.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_10.w_1; sourceTree = "<group>"; };
C2C08E072142748D00C69DBF /* depthwise_conv2d_11.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_11.w_0; sourceTree = "<group>"; };
C2C08E082142748D00C69DBF /* depthwise_conv2d_3.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_3.w_0; sourceTree = "<group>"; };
C2C08E092142748D00C69DBF /* batch_norm_13.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_13.b_0; sourceTree = "<group>"; };
C2C08E0A2142748D00C69DBF /* conv2d_23.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_23.w_0; sourceTree = "<group>"; };
C2C08E0B2142748D00C69DBF /* batch_norm_20.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_20.w_2; sourceTree = "<group>"; };
C2C08E0C2142748D00C69DBF /* batch_norm_34.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_34.w_2; sourceTree = "<group>"; };
C2C08E0D2142748D00C69DBF /* batch_norm_21.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_21.w_2; sourceTree = "<group>"; };
C2C08E0E2142748D00C69DBF /* conv2d_22.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_22.w_0; sourceTree = "<group>"; };
C2C08E0F2142748D00C69DBF /* batch_norm_12.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_12.b_0; sourceTree = "<group>"; };
C2C08E102142748D00C69DBF /* depthwise_conv2d_2.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_2.w_0; sourceTree = "<group>"; };
C2C08E112142748D00C69DBF /* depthwise_conv2d_0.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_0.w_0; sourceTree = "<group>"; };
C2C08E122142748D00C69DBF /* batch_norm_10.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_10.b_0; sourceTree = "<group>"; };
C2C08E132142748D00C69DBF /* conv2d_20.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_20.w_0; sourceTree = "<group>"; };
C2C08E142142748D00C69DBF /* batch_norm_23.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_23.w_2; sourceTree = "<group>"; };
C2C08E152142748D00C69DBF /* batch_norm_22.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_22.w_2; sourceTree = "<group>"; };
C2C08E162142748D00C69DBF /* conv2d_21.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_21.w_0; sourceTree = "<group>"; };
C2C08E172142748D00C69DBF /* batch_norm_11.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_11.b_0; sourceTree = "<group>"; };
C2C08E182142748D00C69DBF /* depthwise_conv2d_1.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_1.w_0; sourceTree = "<group>"; };
C2C08E192142748D00C69DBF /* depthwise_conv2d_5.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_5.w_0; sourceTree = "<group>"; };
C2C08E1A2142748D00C69DBF /* batch_norm_8.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_8.w_0; sourceTree = "<group>"; };
C2C08E1B2142748D00C69DBF /* conv2d_25.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_25.w_0; sourceTree = "<group>"; };
C2C08E1C2142748D00C69DBF /* batch_norm_29.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_29.b_0; sourceTree = "<group>"; };
C2C08E1D2142748D00C69DBF /* conv2d_31.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_31.w_0; sourceTree = "<group>"; };
C2C08E1E2142748D00C69DBF /* conv2d_19.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_19.w_0; sourceTree = "<group>"; };
C2C08E1F2142748D00C69DBF /* batch_norm_15.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_15.b_0; sourceTree = "<group>"; };
C2C08E202142748D00C69DBF /* batch_norm_32.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_32.w_2; sourceTree = "<group>"; };
C2C08E212142748D00C69DBF /* batch_norm_26.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_26.w_2; sourceTree = "<group>"; };
C2C08E222142748D00C69DBF /* batch_norm_27.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_27.w_2; sourceTree = "<group>"; };
C2C08E232142748D00C69DBF /* batch_norm_33.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_33.w_2; sourceTree = "<group>"; };
C2C08E242142748D00C69DBF /* conv2d_18.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_18.w_0; sourceTree = "<group>"; };
C2C08E252142748D00C69DBF /* batch_norm_14.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_14.b_0; sourceTree = "<group>"; };
C2C08E262142748D00C69DBF /* conv2d_30.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_30.w_0; sourceTree = "<group>"; };
C2C08E272142748D00C69DBF /* conv2d_24.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_24.w_0; sourceTree = "<group>"; };
C2C08E282142748D00C69DBF /* batch_norm_28.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_28.b_0; sourceTree = "<group>"; };
C2C08E292142748D00C69DBF /* batch_norm_9.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_9.w_0; sourceTree = "<group>"; };
C2C08E2A2142748D00C69DBF /* depthwise_conv2d_4.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_4.w_0; sourceTree = "<group>"; };
C2C08E2B2142748D00C69DBF /* depthwise_conv2d_6.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_6.w_0; sourceTree = "<group>"; };
C2C08E2C2142748D00C69DBF /* conv2d_32.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_32.w_0; sourceTree = "<group>"; };
C2C08E2D2142748D00C69DBF /* conv2d_26.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_26.w_0; sourceTree = "<group>"; };
C2C08E2E2142748D00C69DBF /* batch_norm_16.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_16.b_0; sourceTree = "<group>"; };
C2C08E2F2142748D00C69DBF /* batch_norm_19.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_19.w_2; sourceTree = "<group>"; };
C2C08E302142748D00C69DBF /* batch_norm_25.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_25.w_2; sourceTree = "<group>"; };
C2C08E312142748D00C69DBF /* batch_norm_31.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_31.w_2; sourceTree = "<group>"; };
C2C08E322142748D00C69DBF /* batch_norm_8.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_8.w_1; sourceTree = "<group>"; };
C2C08E332142748D00C69DBF /* batch_norm_9.w_1 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_9.w_1; sourceTree = "<group>"; };
C2C08E342142748D00C69DBF /* batch_norm_30.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_30.w_2; sourceTree = "<group>"; };
C2C08E352142748D00C69DBF /* batch_norm_24.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_24.w_2; sourceTree = "<group>"; };
C2C08E362142748D00C69DBF /* batch_norm_18.w_2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_18.w_2; sourceTree = "<group>"; };
C2C08E372142748D00C69DBF /* batch_norm_17.b_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = batch_norm_17.b_0; sourceTree = "<group>"; };
C2C08E382142748D00C69DBF /* conv2d_27.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_27.w_0; sourceTree = "<group>"; };
C2C08E392142748D00C69DBF /* conv2d_33.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = conv2d_33.w_0; sourceTree = "<group>"; };
C2C08E3A2142748D00C69DBF /* depthwise_conv2d_7.w_0 */ = {isa = PBXFileReference; lastKnownFileType = file; path = depthwise_conv2d_7.w_0; sourceTree = "<group>"; };
FC013927210204A3008100E3 /* PreProcessKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = PreProcessKernel.metal; sourceTree = "<group>"; }; FC013927210204A3008100E3 /* PreProcessKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = PreProcessKernel.metal; sourceTree = "<group>"; };
FC039B7E20E11C550081E9F8 /* paddle-mobile-demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "paddle-mobile-demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; FC039B7E20E11C550081E9F8 /* paddle-mobile-demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "paddle-mobile-demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
FC039B8120E11C550081E9F8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; FC039B8120E11C550081E9F8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
...@@ -485,8 +63,24 @@ ...@@ -485,8 +63,24 @@
FC039B8D20E11C560081E9F8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; FC039B8D20E11C560081E9F8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
FC27991121343A39000B6BAD /* paddle-mobile-demo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "paddle-mobile-demo-Bridging-Header.h"; sourceTree = "<group>"; }; FC27991121343A39000B6BAD /* paddle-mobile-demo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "paddle-mobile-demo-Bridging-Header.h"; sourceTree = "<group>"; };
FC4FD97B2140EE250073E130 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; FC4FD97B2140EE250073E130 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
FC803BCB214D27920094B8E5 /* FPSCounter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FPSCounter.swift; sourceTree = "<group>"; };
FC803BCC214D27920094B8E5 /* VideoCapture.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoCapture.swift; sourceTree = "<group>"; };
FC8CFEE42135452B0094D569 /* genet_params */ = {isa = PBXFileReference; lastKnownFileType = file; path = genet_params; sourceTree = "<group>"; };
FC8CFEE52135452B0094D569 /* genet_model */ = {isa = PBXFileReference; lastKnownFileType = file; path = genet_model; sourceTree = "<group>"; };
FC8CFEF6213551D00094D569 /* params */ = {isa = PBXFileReference; lastKnownFileType = file; path = params; sourceTree = "<group>"; };
FC8CFEF7213551D00094D569 /* model */ = {isa = PBXFileReference; lastKnownFileType = file; path = model; sourceTree = "<group>"; };
FC918190211DBC3500B6F354 /* paddle-mobile.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "paddle-mobile.png"; sourceTree = "<group>"; };
FC918192211DC70500B6F354 /* iphone.JPG */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = iphone.JPG; sourceTree = "<group>"; };
FC9A19E52148C38400CD9CBF /* ar_model */ = {isa = PBXFileReference; lastKnownFileType = file; path = ar_model; sourceTree = "<group>"; };
FC9A19E62148C38400CD9CBF /* ar_params */ = {isa = PBXFileReference; lastKnownFileType = file; path = ar_params; sourceTree = "<group>"; };
FCA3A16021313E1F00084FE5 /* hand.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hand.jpg; sourceTree = "<group>"; };
FCBCCC502122EEDC00D94F7E /* ssd_hand_params */ = {isa = PBXFileReference; lastKnownFileType = file; path = ssd_hand_params; sourceTree = "<group>"; };
FCBCCC512122EEDC00D94F7E /* ssd_hand_model */ = {isa = PBXFileReference; lastKnownFileType = file; path = ssd_hand_model; sourceTree = "<group>"; };
FCBCCC542122EF5400D94F7E /* MetalHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalHelper.swift; sourceTree = "<group>"; }; FCBCCC542122EF5400D94F7E /* MetalHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalHelper.swift; sourceTree = "<group>"; };
FCDFD41A211D91C7005AB38B /* synset.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = synset.txt; sourceTree = "<group>"; };
FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = paddle_mobile.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = paddle_mobile.framework; sourceTree = BUILT_PRODUCTS_DIR; };
FCEEE7D3210627A000444BEC /* banana.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = banana.jpeg; sourceTree = "<group>"; };
FCF437E7214B6DDB00943429 /* MultiPredictViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPredictViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -520,338 +114,121 @@ ...@@ -520,338 +114,121 @@
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C23717852148E5A50092444E /* fluid_fssd_new_ar */ = { FC039B7520E11C550081E9F8 = {
isa = PBXGroup;
children = (
C23717862148E5A50092444E /* ar_model */,
C23717872148E5A50092444E /* ar_params */,
);
path = fluid_fssd_new_ar;
sourceTree = "<group>";
};
C2C08D5A2142748D00C69DBF /* images */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C2C08D5B2142748D00C69DBF /* synset.txt */, FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */,
C2C08D5C2142748D00C69DBF /* banana.jpeg */, FC039B8020E11C550081E9F8 /* paddle-mobile-demo */,
C2C08D5D2142748D00C69DBF /* hand.jpg */, FC039B7F20E11C550081E9F8 /* Products */,
C2C08D5E2142748D00C69DBF /* iphone.JPG */, 5722B50FEC38F55CA9B6A57B /* Pods */,
C2C08D5F2142748D00C69DBF /* paddle-mobile.png */, 7B7DED984E9EE7BFB45E24E8 /* Frameworks */,
); );
path = images;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C2C08D602142748D00C69DBF /* models */ = { FC039B7F20E11C550081E9F8 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C23717852148E5A50092444E /* fluid_fssd_new_ar */, FC039B7E20E11C550081E9F8 /* paddle-mobile-demo.app */,
C2C08D612142748D00C69DBF /* mobilenet */,
C2C08D642142748D00C69DBF /* genet */,
C2C08D672142748D00C69DBF /* mobilenet_ssd_hand */,
C2C08D6A2142748D00C69DBF /* yolo */,
C2C08D6F2142748D00C69DBF /* mobilenet_combine */,
C2C08D722142748D00C69DBF /* mobilenetssd */,
); );
path = models; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C2C08D612142748D00C69DBF /* mobilenet */ = { FC039B8020E11C550081E9F8 /* paddle-mobile-demo */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C2C08D622142748D00C69DBF /* params */, FC803BCA214D27920094B8E5 /* VideoCapture */,
C2C08D632142748D00C69DBF /* model */, FC8CFED2213519540094D569 /* Net */,
FC0E2C2020EDC03B009C1FAC /* models */,
FC0E2C1D20EDC030009C1FAC /* images */,
FC039B8120E11C550081E9F8 /* AppDelegate.swift */,
FC039B8320E11C550081E9F8 /* ViewController.swift */,
FC039B8520E11C550081E9F8 /* Main.storyboard */,
FC039B8820E11C560081E9F8 /* Assets.xcassets */,
FC039B8A20E11C560081E9F8 /* LaunchScreen.storyboard */,
FC039B8D20E11C560081E9F8 /* Info.plist */,
FC27991121343A39000B6BAD /* paddle-mobile-demo-Bridging-Header.h */,
FCF437E7214B6DDB00943429 /* MultiPredictViewController.swift */,
); );
path = mobilenet; path = "paddle-mobile-demo";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C2C08D642142748D00C69DBF /* genet */ = { FC0E2C1D20EDC030009C1FAC /* images */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C2C08D652142748D00C69DBF /* genet_params */, FCA3A16021313E1F00084FE5 /* hand.jpg */,
C2C08D662142748D00C69DBF /* genet_model */, FC918192211DC70500B6F354 /* iphone.JPG */,
); FC918190211DBC3500B6F354 /* paddle-mobile.png */,
path = genet; FCDFD41A211D91C7005AB38B /* synset.txt */,
FCEEE7D3210627A000444BEC /* banana.jpeg */,
);
name = images;
path = ../../images;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C2C08D672142748D00C69DBF /* mobilenet_ssd_hand */ = { FC0E2C2020EDC03B009C1FAC /* models */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C2C08D682142748D00C69DBF /* ssd_hand_params */, FC9A19E42148C38400CD9CBF /* fluid_fssd_new_ar */,
C2C08D692142748D00C69DBF /* ssd_hand_model */, FC8CFEF5213551D00094D569 /* mobilenet */,
FC8CFEE32135452B0094D569 /* genet */,
FCBCCC4F2122EEDC00D94F7E /* mobilenet_ssd_hand */,
); );
path = mobilenet_ssd_hand; name = models;
path = ../../models;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C2C08D6A2142748D00C69DBF /* yolo */ = { FC803BCA214D27920094B8E5 /* VideoCapture */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C2C08D6B2142748D00C69DBF /* mobilenet */, FC803BCB214D27920094B8E5 /* FPSCounter.swift */,
C2C08D6C2142748D00C69DBF /* params */, FC803BCC214D27920094B8E5 /* VideoCapture.swift */,
C2C08D6D2142748D00C69DBF /* model */,
C2C08D6E2142748D00C69DBF /* yolo */,
); );
path = yolo; path = VideoCapture;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C2C08D6F2142748D00C69DBF /* mobilenet_combine */ = { FC8CFED2213519540094D569 /* Net */ = {
isa = PBXGroup;
children = (
C2C08D702142748D00C69DBF /* params */,
C2C08D712142748D00C69DBF /* model */,
);
path = mobilenet_combine;
sourceTree = "<group>";
};
C2C08D722142748D00C69DBF /* mobilenetssd */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C2C08D732142748D00C69DBF /* batch_norm_7.w_0 */, FC013927210204A3008100E3 /* PreProcessKernel.metal */,
C2C08D742142748D00C69DBF /* batch_norm_26.b_0 */, FCBCCC542122EF5400D94F7E /* MetalHelper.swift */,
C2C08D752142748D00C69DBF /* batch_norm_32.b_0 */,
C2C08D762142748D00C69DBF /* conv2d_16.w_0 */,
C2C08D772142748D00C69DBF /* batch_norm_15.w_2 */,
C2C08D782142748D00C69DBF /* batch_norm_29.w_2 */,
C2C08D792142748D00C69DBF /* batch_norm_4.w_1 */,
C2C08D7A2142748D00C69DBF /* batch_norm_5.w_1 */,
C2C08D7B2142748D00C69DBF /* batch_norm_28.w_2 */,
C2C08D7C2142748D00C69DBF /* batch_norm_14.w_2 */,
C2C08D7D2142748D00C69DBF /* conv2d_17.w_0 */,
C2C08D7E2142748D00C69DBF /* batch_norm_33.b_0 */,
C2C08D7F2142748D00C69DBF /* batch_norm_27.b_0 */,
C2C08D802142748D00C69DBF /* batch_norm_6.w_0 */,
C2C08D812142748D00C69DBF /* batch_norm_4.w_0 */,
C2C08D822142748D00C69DBF /* depthwise_conv2d_9.w_0 */,
C2C08D832142748D00C69DBF /* batch_norm_31.b_0 */,
C2C08D842142748D00C69DBF /* conv2d_29.w_0 */,
C2C08D852142748D00C69DBF /* batch_norm_25.b_0 */,
C2C08D862142748D00C69DBF /* conv2d_15.w_0 */,
C2C08D872142748D00C69DBF /* batch_norm_19.b_0 */,
C2C08D882142748D00C69DBF /* batch_norm_16.w_2 */,
C2C08D892142748D00C69DBF /* __model__ */,
C2C08D8A2142748D00C69DBF /* batch_norm_7.w_1 */,
C2C08D8B2142748D00C69DBF /* batch_norm_6.w_1 */,
C2C08D8C2142748D00C69DBF /* batch_norm_17.w_2 */,
C2C08D8D2142748D00C69DBF /* conv2d_14.w_0 */,
C2C08D8E2142748D00C69DBF /* batch_norm_18.b_0 */,
C2C08D8F2142748D00C69DBF /* conv2d_28.w_0 */,
C2C08D902142748D00C69DBF /* batch_norm_24.b_0 */,
C2C08D912142748D00C69DBF /* batch_norm_30.b_0 */,
C2C08D922142748D00C69DBF /* depthwise_conv2d_8.w_0 */,
C2C08D932142748D00C69DBF /* batch_norm_5.w_0 */,
C2C08D942142748D00C69DBF /* batch_norm_1.w_0 */,
C2C08D952142748D00C69DBF /* conv2d_10.w_0 */,
C2C08D962142748D00C69DBF /* batch_norm_34.b_0 */,
C2C08D972142748D00C69DBF /* batch_norm_20.b_0 */,
C2C08D982142748D00C69DBF /* batch_norm_13.w_2 */,
C2C08D992142748D00C69DBF /* batch_norm_2.w_1 */,
C2C08D9A2142748D00C69DBF /* batch_norm_3.w_1 */,
C2C08D9B2142748D00C69DBF /* batch_norm_12.w_2 */,
C2C08D9C2142748D00C69DBF /* batch_norm_21.b_0 */,
C2C08D9D2142748D00C69DBF /* conv2d_11.w_0 */,
C2C08D9E2142748D00C69DBF /* batch_norm_0.w_0 */,
C2C08D9F2142748D00C69DBF /* batch_norm_2.w_0 */,
C2C08DA02142748D00C69DBF /* conv2d_13.w_0 */,
C2C08DA12142748D00C69DBF /* batch_norm_23.b_0 */,
C2C08DA22142748D00C69DBF /* batch_norm_10.w_2 */,
C2C08DA32142748D00C69DBF /* batch_norm_1.w_1 */,
C2C08DA42142748D00C69DBF /* batch_norm_0.w_1 */,
C2C08DA52142748D00C69DBF /* batch_norm_11.w_2 */,
C2C08DA62142748D00C69DBF /* batch_norm_22.b_0 */,
C2C08DA72142748D00C69DBF /* conv2d_12.w_0 */,
C2C08DA82142748D00C69DBF /* batch_norm_3.w_0 */,
C2C08DA92142748D00C69DBF /* batch_norm_21.w_1 */,
C2C08DAA2142748D00C69DBF /* batch_norm_3.b_0 */,
C2C08DAB2142748D00C69DBF /* batch_norm_22.w_0 */,
C2C08DAC2142748D00C69DBF /* batch_norm_23.w_0 */,
C2C08DAD2142748D00C69DBF /* batch_norm_2.b_0 */,
C2C08DAE2142748D00C69DBF /* batch_norm_20.w_1 */,
C2C08DAF2142748D00C69DBF /* batch_norm_34.w_1 */,
C2C08DB02142748D00C69DBF /* batch_norm_22.w_1 */,
C2C08DB12142748D00C69DBF /* batch_norm_0.b_0 */,
C2C08DB22142748D00C69DBF /* batch_norm_21.w_0 */,
C2C08DB32142748D00C69DBF /* batch_norm_20.w_0 */,
C2C08DB42142748D00C69DBF /* batch_norm_34.w_0 */,
C2C08DB52142748D00C69DBF /* batch_norm_1.b_0 */,
C2C08DB62142748D00C69DBF /* batch_norm_23.w_1 */,
C2C08DB72142748D00C69DBF /* batch_norm_27.w_1 */,
C2C08DB82142748D00C69DBF /* batch_norm_33.w_1 */,
C2C08DB92142748D00C69DBF /* batch_norm_5.b_0 */,
C2C08DBA2142748D00C69DBF /* batch_norm_18.w_0 */,
C2C08DBB2142748D00C69DBF /* batch_norm_30.w_0 */,
C2C08DBC2142748D00C69DBF /* batch_norm_24.w_0 */,
C2C08DBD2142748D00C69DBF /* conv2d_28.b_0 */,
C2C08DBE2142748D00C69DBF /* batch_norm_25.w_0 */,
C2C08DBF2142748D00C69DBF /* conv2d_29.b_0 */,
C2C08DC02142748D00C69DBF /* batch_norm_31.w_0 */,
C2C08DC12142748D00C69DBF /* batch_norm_19.w_0 */,
C2C08DC22142748D00C69DBF /* batch_norm_4.b_0 */,
C2C08DC32142748D00C69DBF /* batch_norm_32.w_1 */,
C2C08DC42142748D00C69DBF /* batch_norm_26.w_1 */,
C2C08DC52142748D00C69DBF /* batch_norm_30.w_1 */,
C2C08DC62142748D00C69DBF /* batch_norm_24.w_1 */,
C2C08DC72142748D00C69DBF /* batch_norm_18.w_1 */,
C2C08DC82142748D00C69DBF /* batch_norm_6.b_0 */,
C2C08DC92142748D00C69DBF /* batch_norm_9.w_2 */,
C2C08DCA2142748D00C69DBF /* conv2d_8.w_0 */,
C2C08DCB2142748D00C69DBF /* batch_norm_27.w_0 */,
C2C08DCC2142748D00C69DBF /* batch_norm_33.w_0 */,
C2C08DCD2142748D00C69DBF /* batch_norm_32.w_0 */,
C2C08DCE2142748D00C69DBF /* conv2d_9.w_0 */,
C2C08DCF2142748D00C69DBF /* batch_norm_26.w_0 */,
C2C08DD02142748D00C69DBF /* batch_norm_8.w_2 */,
C2C08DD12142748D00C69DBF /* batch_norm_7.b_0 */,
C2C08DD22142748D00C69DBF /* batch_norm_19.w_1 */,
C2C08DD32142748D00C69DBF /* batch_norm_25.w_1 */,
C2C08DD42142748D00C69DBF /* batch_norm_31.w_1 */,
C2C08DD52142748D00C69DBF /* batch_norm_28.w_1 */,
C2C08DD62142748D00C69DBF /* batch_norm_14.w_1 */,
C2C08DD72142748D00C69DBF /* batch_norm_5.w_2 */,
C2C08DD82142748D00C69DBF /* batch_norm_17.w_0 */,
C2C08DD92142748D00C69DBF /* conv2d_33.b_0 */,
C2C08DDA2142748D00C69DBF /* conv2d_27.b_0 */,
C2C08DDB2142748D00C69DBF /* conv2d_4.w_0 */,
C2C08DDC2142748D00C69DBF /* conv2d_5.w_0 */,
C2C08DDD2142748D00C69DBF /* conv2d_26.b_0 */,
C2C08DDE2142748D00C69DBF /* conv2d_32.b_0 */,
C2C08DDF2142748D00C69DBF /* batch_norm_16.w_0 */,
C2C08DE02142748D00C69DBF /* batch_norm_4.w_2 */,
C2C08DE12142748D00C69DBF /* batch_norm_15.w_1 */,
C2C08DE22142748D00C69DBF /* batch_norm_29.w_1 */,
C2C08DE32142748D00C69DBF /* batch_norm_17.w_1 */,
C2C08DE42142748D00C69DBF /* batch_norm_9.b_0 */,
C2C08DE52142748D00C69DBF /* batch_norm_6.w_2 */,
C2C08DE62142748D00C69DBF /* batch_norm_14.w_0 */,
C2C08DE72142748D00C69DBF /* batch_norm_28.w_0 */,
C2C08DE82142748D00C69DBF /* conv2d_24.b_0 */,
C2C08DE92142748D00C69DBF /* conv2d_7.w_0 */,
C2C08DEA2142748D00C69DBF /* conv2d_30.b_0 */,
C2C08DEB2142748D00C69DBF /* conv2d_31.b_0 */,
C2C08DEC2142748D00C69DBF /* batch_norm_29.w_0 */,
C2C08DED2142748D00C69DBF /* conv2d_6.w_0 */,
C2C08DEE2142748D00C69DBF /* conv2d_25.b_0 */,
C2C08DEF2142748D00C69DBF /* batch_norm_15.w_0 */,
C2C08DF02142748D00C69DBF /* batch_norm_7.w_2 */,
C2C08DF12142748D00C69DBF /* batch_norm_8.b_0 */,
C2C08DF22142748D00C69DBF /* batch_norm_16.w_1 */,
C2C08DF32142748D00C69DBF /* batch_norm_12.w_1 */,
C2C08DF42142748D00C69DBF /* batch_norm_3.w_2 */,
C2C08DF52142748D00C69DBF /* conv2d_2.w_0 */,
C2C08DF62142748D00C69DBF /* batch_norm_11.w_0 */,
C2C08DF72142748D00C69DBF /* batch_norm_10.w_0 */,
C2C08DF82142748D00C69DBF /* conv2d_3.w_0 */,
C2C08DF92142748D00C69DBF /* batch_norm_2.w_2 */,
C2C08DFA2142748D00C69DBF /* depthwise_conv2d_12.w_0 */,
C2C08DFB2142748D00C69DBF /* batch_norm_13.w_1 */,
C2C08DFC2142748D00C69DBF /* batch_norm_11.w_1 */,
C2C08DFD2142748D00C69DBF /* depthwise_conv2d_10.w_0 */,
C2C08DFE2142748D00C69DBF /* batch_norm_0.w_2 */,
C2C08DFF2142748D00C69DBF /* conv2d_22.b_0 */,
C2C08E002142748D00C69DBF /* conv2d_1.w_0 */,
C2C08E012142748D00C69DBF /* batch_norm_12.w_0 */,
C2C08E022142748D00C69DBF /* batch_norm_13.w_0 */,
C2C08E032142748D00C69DBF /* conv2d_0.w_0 */,
C2C08E042142748D00C69DBF /* conv2d_23.b_0 */,
C2C08E052142748D00C69DBF /* batch_norm_1.w_2 */,
C2C08E062142748D00C69DBF /* batch_norm_10.w_1 */,
C2C08E072142748D00C69DBF /* depthwise_conv2d_11.w_0 */,
C2C08E082142748D00C69DBF /* depthwise_conv2d_3.w_0 */,
C2C08E092142748D00C69DBF /* batch_norm_13.b_0 */,
C2C08E0A2142748D00C69DBF /* conv2d_23.w_0 */,
C2C08E0B2142748D00C69DBF /* batch_norm_20.w_2 */,
C2C08E0C2142748D00C69DBF /* batch_norm_34.w_2 */,
C2C08E0D2142748D00C69DBF /* batch_norm_21.w_2 */,
C2C08E0E2142748D00C69DBF /* conv2d_22.w_0 */,
C2C08E0F2142748D00C69DBF /* batch_norm_12.b_0 */,
C2C08E102142748D00C69DBF /* depthwise_conv2d_2.w_0 */,
C2C08E112142748D00C69DBF /* depthwise_conv2d_0.w_0 */,
C2C08E122142748D00C69DBF /* batch_norm_10.b_0 */,
C2C08E132142748D00C69DBF /* conv2d_20.w_0 */,
C2C08E142142748D00C69DBF /* batch_norm_23.w_2 */,
C2C08E152142748D00C69DBF /* batch_norm_22.w_2 */,
C2C08E162142748D00C69DBF /* conv2d_21.w_0 */,
C2C08E172142748D00C69DBF /* batch_norm_11.b_0 */,
C2C08E182142748D00C69DBF /* depthwise_conv2d_1.w_0 */,
C2C08E192142748D00C69DBF /* depthwise_conv2d_5.w_0 */,
C2C08E1A2142748D00C69DBF /* batch_norm_8.w_0 */,
C2C08E1B2142748D00C69DBF /* conv2d_25.w_0 */,
C2C08E1C2142748D00C69DBF /* batch_norm_29.b_0 */,
C2C08E1D2142748D00C69DBF /* conv2d_31.w_0 */,
C2C08E1E2142748D00C69DBF /* conv2d_19.w_0 */,
C2C08E1F2142748D00C69DBF /* batch_norm_15.b_0 */,
C2C08E202142748D00C69DBF /* batch_norm_32.w_2 */,
C2C08E212142748D00C69DBF /* batch_norm_26.w_2 */,
C2C08E222142748D00C69DBF /* batch_norm_27.w_2 */,
C2C08E232142748D00C69DBF /* batch_norm_33.w_2 */,
C2C08E242142748D00C69DBF /* conv2d_18.w_0 */,
C2C08E252142748D00C69DBF /* batch_norm_14.b_0 */,
C2C08E262142748D00C69DBF /* conv2d_30.w_0 */,
C2C08E272142748D00C69DBF /* conv2d_24.w_0 */,
C2C08E282142748D00C69DBF /* batch_norm_28.b_0 */,
C2C08E292142748D00C69DBF /* batch_norm_9.w_0 */,
C2C08E2A2142748D00C69DBF /* depthwise_conv2d_4.w_0 */,
C2C08E2B2142748D00C69DBF /* depthwise_conv2d_6.w_0 */,
C2C08E2C2142748D00C69DBF /* conv2d_32.w_0 */,
C2C08E2D2142748D00C69DBF /* conv2d_26.w_0 */,
C2C08E2E2142748D00C69DBF /* batch_norm_16.b_0 */,
C2C08E2F2142748D00C69DBF /* batch_norm_19.w_2 */,
C2C08E302142748D00C69DBF /* batch_norm_25.w_2 */,
C2C08E312142748D00C69DBF /* batch_norm_31.w_2 */,
C2C08E322142748D00C69DBF /* batch_norm_8.w_1 */,
C2C08E332142748D00C69DBF /* batch_norm_9.w_1 */,
C2C08E342142748D00C69DBF /* batch_norm_30.w_2 */,
C2C08E352142748D00C69DBF /* batch_norm_24.w_2 */,
C2C08E362142748D00C69DBF /* batch_norm_18.w_2 */,
C2C08E372142748D00C69DBF /* batch_norm_17.b_0 */,
C2C08E382142748D00C69DBF /* conv2d_27.w_0 */,
C2C08E392142748D00C69DBF /* conv2d_33.w_0 */,
C2C08E3A2142748D00C69DBF /* depthwise_conv2d_7.w_0 */,
); );
path = mobilenetssd; path = Net;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
FC039B7520E11C550081E9F8 = { FC8CFEE32135452B0094D569 /* genet */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FCEBEC2B20E1391F00C0B14D /* paddle_mobile.framework */, FC8CFEE42135452B0094D569 /* genet_params */,
FC039B8020E11C550081E9F8 /* paddle-mobile-demo */, FC8CFEE52135452B0094D569 /* genet_model */,
FC039B7F20E11C550081E9F8 /* Products */,
5722B50FEC38F55CA9B6A57B /* Pods */,
7B7DED984E9EE7BFB45E24E8 /* Frameworks */,
); );
path = genet;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
FC039B7F20E11C550081E9F8 /* Products */ = { FC8CFEF5213551D00094D569 /* mobilenet */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FC039B7E20E11C550081E9F8 /* paddle-mobile-demo.app */, FC8CFEF6213551D00094D569 /* params */,
FC8CFEF7213551D00094D569 /* model */,
); );
name = Products; path = mobilenet;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
FC039B8020E11C550081E9F8 /* paddle-mobile-demo */ = { FC9A19E42148C38400CD9CBF /* fluid_fssd_new_ar */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C2C08D5A2142748D00C69DBF /* images */, FC9A19E52148C38400CD9CBF /* ar_model */,
C2C08D602142748D00C69DBF /* models */, FC9A19E62148C38400CD9CBF /* ar_params */,
FC8CFED2213519540094D569 /* Net */,
FC039B8120E11C550081E9F8 /* AppDelegate.swift */,
FC039B8320E11C550081E9F8 /* ViewController.swift */,
FC039B8520E11C550081E9F8 /* Main.storyboard */,
FC039B8820E11C560081E9F8 /* Assets.xcassets */,
FC039B8A20E11C560081E9F8 /* LaunchScreen.storyboard */,
FC039B8D20E11C560081E9F8 /* Info.plist */,
FC27991121343A39000B6BAD /* paddle-mobile-demo-Bridging-Header.h */,
); );
path = "paddle-mobile-demo"; path = fluid_fssd_new_ar;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
FC8CFED2213519540094D569 /* Net */ = { FCBCCC4F2122EEDC00D94F7E /* mobilenet_ssd_hand */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FC013927210204A3008100E3 /* PreProcessKernel.metal */, FCBCCC502122EEDC00D94F7E /* ssd_hand_params */,
FCBCCC542122EF5400D94F7E /* MetalHelper.swift */, FCBCCC512122EEDC00D94F7E /* ssd_hand_model */,
); );
path = Net; path = mobilenet_ssd_hand;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
/* End PBXGroup section */ /* End PBXGroup section */
...@@ -916,228 +293,22 @@ ...@@ -916,228 +293,22 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
FC8CFEF8213551D10094D569 /* params in Resources */,
FC039B8C20E11C560081E9F8 /* LaunchScreen.storyboard in Resources */, FC039B8C20E11C560081E9F8 /* LaunchScreen.storyboard in Resources */,
C2C08E722142748D00C69DBF /* batch_norm_2.w_1 in Resources */, FC8CFEF9213551D10094D569 /* model in Resources */,
C2C08EB22142748D00C69DBF /* conv2d_33.b_0 in Resources */, FC918191211DBC3500B6F354 /* paddle-mobile.png in Resources */,
C2C08E522142748D00C69DBF /* batch_norm_4.w_1 in Resources */, FC8CFEE72135452C0094D569 /* genet_model in Resources */,
C2C08ED92142748D00C69DBF /* conv2d_1.w_0 in Resources */,
C2C08E612142748D00C69DBF /* batch_norm_16.w_2 in Resources */,
C2C08E7C2142748D00C69DBF /* batch_norm_1.w_1 in Resources */,
C2C08EE62142748D00C69DBF /* batch_norm_21.w_2 in Resources */,
C2C08E3C2142748D00C69DBF /* banana.jpeg in Resources */,
C2C08EA92142748D00C69DBF /* batch_norm_8.w_2 in Resources */,
C2C08EA82142748D00C69DBF /* batch_norm_26.w_0 in Resources */,
C2C08EDC2142748D00C69DBF /* conv2d_0.w_0 in Resources */,
C2C08EBE2142748D00C69DBF /* batch_norm_6.w_2 in Resources */,
C2C08E4A2142748D00C69DBF /* params in Resources */,
C2C08EE32142748D00C69DBF /* conv2d_23.w_0 in Resources */,
C2C08EE52142748D00C69DBF /* batch_norm_34.w_2 in Resources */,
C2C08E672142748D00C69DBF /* batch_norm_18.b_0 in Resources */,
C2C08E972142748D00C69DBF /* batch_norm_25.w_0 in Resources */,
C2C08E432142748D00C69DBF /* genet_model in Resources */,
C2C08EFC2142748D00C69DBF /* batch_norm_33.w_2 in Resources */,
C2C08EC72142748D00C69DBF /* conv2d_25.b_0 in Resources */,
C2C08EB62142748D00C69DBF /* conv2d_26.b_0 in Resources */,
C2C08F0C2142748D00C69DBF /* batch_norm_9.w_1 in Resources */,
C2C08E5E2142748D00C69DBF /* batch_norm_25.b_0 in Resources */,
C2C08E832142748D00C69DBF /* batch_norm_3.b_0 in Resources */,
C2C08ED42142748D00C69DBF /* batch_norm_13.w_1 in Resources */,
C2C08EC42142748D00C69DBF /* conv2d_31.b_0 in Resources */,
C2C08E582142748D00C69DBF /* batch_norm_27.b_0 in Resources */,
C2C08E442142748D00C69DBF /* ssd_hand_params in Resources */,
C2C08E562142748D00C69DBF /* conv2d_17.w_0 in Resources */,
C2C08E8E2142748D00C69DBF /* batch_norm_1.b_0 in Resources */,
C2C08ED52142748D00C69DBF /* batch_norm_11.w_1 in Resources */,
C2C08F042142748D00C69DBF /* depthwise_conv2d_6.w_0 in Resources */,
C2C08E8A2142748D00C69DBF /* batch_norm_0.b_0 in Resources */,
C2C08E9E2142748D00C69DBF /* batch_norm_30.w_1 in Resources */,
C2C08EFB2142748D00C69DBF /* batch_norm_27.w_2 in Resources */,
C2C08E882142748D00C69DBF /* batch_norm_34.w_1 in Resources */,
C2C08E6C2142748D00C69DBF /* batch_norm_5.w_0 in Resources */,
C2C08E532142748D00C69DBF /* batch_norm_5.w_1 in Resources */,
C2C08EAF2142748D00C69DBF /* batch_norm_14.w_1 in Resources */,
C2C08F082142748D00C69DBF /* batch_norm_19.w_2 in Resources */,
C2C08E9D2142748D00C69DBF /* batch_norm_26.w_1 in Resources */,
C2C08EEC2142748D00C69DBF /* conv2d_20.w_0 in Resources */,
C2C08E8C2142748D00C69DBF /* batch_norm_20.w_0 in Resources */,
C2C08EEF2142748D00C69DBF /* conv2d_21.w_0 in Resources */,
C2C08EDF2142748D00C69DBF /* batch_norm_10.w_1 in Resources */,
C2C08EBD2142748D00C69DBF /* batch_norm_9.b_0 in Resources */,
C2C08E652142748D00C69DBF /* batch_norm_17.w_2 in Resources */,
C2C08E902142748D00C69DBF /* batch_norm_27.w_1 in Resources */,
C2C08F112142748D00C69DBF /* conv2d_27.w_0 in Resources */,
C2C08EAA2142748D00C69DBF /* batch_norm_7.b_0 in Resources */,
C2C08E4C2142748D00C69DBF /* batch_norm_7.w_0 in Resources */,
C2C08E402142748D00C69DBF /* params in Resources */,
C2C08E662142748D00C69DBF /* conv2d_14.w_0 in Resources */,
C2C08E4B2142748D00C69DBF /* model in Resources */,
C2C08EFE2142748D00C69DBF /* batch_norm_14.b_0 in Resources */,
C2C08ECD2142748D00C69DBF /* batch_norm_3.w_2 in Resources */,
C2C08E9B2142748D00C69DBF /* batch_norm_4.b_0 in Resources */,
C2C08E842142748D00C69DBF /* batch_norm_22.w_0 in Resources */,
C2C08EB32142748D00C69DBF /* conv2d_27.b_0 in Resources */,
C2C08EA32142748D00C69DBF /* conv2d_8.w_0 in Resources */,
C2C08EA62142748D00C69DBF /* batch_norm_32.w_0 in Resources */,
C2C08E6B2142748D00C69DBF /* depthwise_conv2d_8.w_0 in Resources */,
C2C08E6F2142748D00C69DBF /* batch_norm_34.b_0 in Resources */,
C2C08ED02142748D00C69DBF /* batch_norm_10.w_0 in Resources */,
C2C08EE82142748D00C69DBF /* batch_norm_12.b_0 in Resources */,
C2C08E602142748D00C69DBF /* batch_norm_19.b_0 in Resources */,
C2C08E992142748D00C69DBF /* batch_norm_31.w_0 in Resources */,
C2C08E932142748D00C69DBF /* batch_norm_18.w_0 in Resources */,
C2C08EE02142748D00C69DBF /* depthwise_conv2d_11.w_0 in Resources */,
FC039B8920E11C560081E9F8 /* Assets.xcassets in Resources */, FC039B8920E11C560081E9F8 /* Assets.xcassets in Resources */,
C2C08E4E2142748D00C69DBF /* batch_norm_32.b_0 in Resources */, FCBCCC522122EEDC00D94F7E /* ssd_hand_params in Resources */,
C2C08EE92142748D00C69DBF /* depthwise_conv2d_2.w_0 in Resources */, FCEEE7D4210627A000444BEC /* banana.jpeg in Resources */,
C2C08EC92142748D00C69DBF /* batch_norm_7.w_2 in Resources */, FC918193211DC70500B6F354 /* iphone.JPG in Resources */,
C2C08E8F2142748D00C69DBF /* batch_norm_23.w_1 in Resources */, FCDFD41B211D91C7005AB38B /* synset.txt in Resources */,
C2C08E3F2142748D00C69DBF /* paddle-mobile.png in Resources */,
C2C08E9F2142748D00C69DBF /* batch_norm_24.w_1 in Resources */,
C2C08E4F2142748D00C69DBF /* conv2d_16.w_0 in Resources */,
C2C08E792142748D00C69DBF /* conv2d_13.w_0 in Resources */,
C2C08EBA2142748D00C69DBF /* batch_norm_15.w_1 in Resources */,
C2C08ECF2142748D00C69DBF /* batch_norm_11.w_0 in Resources */,
C2C08EF02142748D00C69DBF /* batch_norm_11.b_0 in Resources */,
C2C08E8B2142748D00C69DBF /* batch_norm_21.w_0 in Resources */,
C2C08E742142748D00C69DBF /* batch_norm_12.w_2 in Resources */,
C2C08E492142748D00C69DBF /* yolo in Resources */,
C2C08E3E2142748D00C69DBF /* iphone.JPG in Resources */,
C2C08E762142748D00C69DBF /* conv2d_11.w_0 in Resources */,
C2C08F102142748D00C69DBF /* batch_norm_17.b_0 in Resources */,
C2C08E7F2142748D00C69DBF /* batch_norm_22.b_0 in Resources */,
C2C08EB12142748D00C69DBF /* batch_norm_17.w_0 in Resources */,
C2C08EF12142748D00C69DBF /* depthwise_conv2d_1.w_0 in Resources */,
C2C08EB52142748D00C69DBF /* conv2d_5.w_0 in Resources */,
C2C08EF32142748D00C69DBF /* batch_norm_8.w_0 in Resources */,
C2C08EB72142748D00C69DBF /* conv2d_32.b_0 in Resources */,
C2C08EF72142748D00C69DBF /* conv2d_19.w_0 in Resources */,
C2C08E782142748D00C69DBF /* batch_norm_2.w_0 in Resources */,
C2C08EF92142748D00C69DBF /* batch_norm_32.w_2 in Resources */,
C2C08E872142748D00C69DBF /* batch_norm_20.w_1 in Resources */,
C2C08E462142748D00C69DBF /* mobilenet in Resources */,
C2C08EBB2142748D00C69DBF /* batch_norm_29.w_1 in Resources */,
C2C08EE42142748D00C69DBF /* batch_norm_20.w_2 in Resources */,
C2C08EFD2142748D00C69DBF /* conv2d_18.w_0 in Resources */,
C2C08E5C2142748D00C69DBF /* batch_norm_31.b_0 in Resources */,
C2C08EF82142748D00C69DBF /* batch_norm_15.b_0 in Resources */,
C2C08E982142748D00C69DBF /* conv2d_29.b_0 in Resources */,
C2C08EEE2142748D00C69DBF /* batch_norm_22.w_2 in Resources */,
C2C08E852142748D00C69DBF /* batch_norm_23.w_0 in Resources */,
C2C08EA12142748D00C69DBF /* batch_norm_6.b_0 in Resources */,
C2C08EA52142748D00C69DBF /* batch_norm_33.w_0 in Resources */,
C2C08E6A2142748D00C69DBF /* batch_norm_30.b_0 in Resources */,
C2C08E572142748D00C69DBF /* batch_norm_33.b_0 in Resources */,
C2C08E7B2142748D00C69DBF /* batch_norm_10.w_2 in Resources */,
C2C08EAE2142748D00C69DBF /* batch_norm_28.w_1 in Resources */,
C2C08EA22142748D00C69DBF /* batch_norm_9.w_2 in Resources */,
C2C08EEA2142748D00C69DBF /* depthwise_conv2d_0.w_0 in Resources */,
C2C08EB82142748D00C69DBF /* batch_norm_16.w_0 in Resources */,
C2C08E5D2142748D00C69DBF /* conv2d_29.w_0 in Resources */,
C2C08E542142748D00C69DBF /* batch_norm_28.w_2 in Resources */,
C2C08EF62142748D00C69DBF /* conv2d_31.w_0 in Resources */,
C2C08E9A2142748D00C69DBF /* batch_norm_19.w_0 in Resources */,
C2C08EEB2142748D00C69DBF /* batch_norm_10.b_0 in Resources */,
C2C08EC32142748D00C69DBF /* conv2d_30.b_0 in Resources */,
C2C08EED2142748D00C69DBF /* batch_norm_23.w_2 in Resources */,
C2C08E452142748D00C69DBF /* ssd_hand_model in Resources */,
C2C08F022142748D00C69DBF /* batch_norm_9.w_0 in Resources */,
C2C08EE12142748D00C69DBF /* depthwise_conv2d_3.w_0 in Resources */,
C2C08EC22142748D00C69DBF /* conv2d_7.w_0 in Resources */,
C2C08EC12142748D00C69DBF /* conv2d_24.b_0 in Resources */,
C2C08E7A2142748D00C69DBF /* batch_norm_23.b_0 in Resources */,
C2C08EC52142748D00C69DBF /* batch_norm_29.w_0 in Resources */,
C2C08ED12142748D00C69DBF /* conv2d_3.w_0 in Resources */,
C2C08E4D2142748D00C69DBF /* batch_norm_26.b_0 in Resources */,
C2C08F0B2142748D00C69DBF /* batch_norm_8.w_1 in Resources */,
C2C08EC62142748D00C69DBF /* conv2d_6.w_0 in Resources */,
C2C08F0A2142748D00C69DBF /* batch_norm_31.w_2 in Resources */,
C2C08E702142748D00C69DBF /* batch_norm_20.b_0 in Resources */,
C2C08EBF2142748D00C69DBF /* batch_norm_14.w_0 in Resources */,
C2C08E482142748D00C69DBF /* model in Resources */,
C2C08EAC2142748D00C69DBF /* batch_norm_25.w_1 in Resources */,
C2C08EB42142748D00C69DBF /* conv2d_4.w_0 in Resources */,
C2C08F032142748D00C69DBF /* depthwise_conv2d_4.w_0 in Resources */,
C2C08E622142748D00C69DBF /* __model__ in Resources */,
C2C08E472142748D00C69DBF /* params in Resources */,
C2C08E502142748D00C69DBF /* batch_norm_15.w_2 in Resources */,
C2C08ECB2142748D00C69DBF /* batch_norm_16.w_1 in Resources */,
C2C08E632142748D00C69DBF /* batch_norm_7.w_1 in Resources */,
C2C08E942142748D00C69DBF /* batch_norm_30.w_0 in Resources */,
C2C08E5B2142748D00C69DBF /* depthwise_conv2d_9.w_0 in Resources */,
C2C08ECA2142748D00C69DBF /* batch_norm_8.b_0 in Resources */,
C2C08EDB2142748D00C69DBF /* batch_norm_13.w_0 in Resources */,
C2C08E412142748D00C69DBF /* model in Resources */,
C23717892148E5A50092444E /* ar_params in Resources */,
C2C08EE22142748D00C69DBF /* batch_norm_13.b_0 in Resources */,
C2C08E952142748D00C69DBF /* batch_norm_24.w_0 in Resources */,
C2C08F072142748D00C69DBF /* batch_norm_16.b_0 in Resources */,
C2C08ED72142748D00C69DBF /* batch_norm_0.w_2 in Resources */,
C2C08E7E2142748D00C69DBF /* batch_norm_11.w_2 in Resources */,
C2C08EB92142748D00C69DBF /* batch_norm_4.w_2 in Resources */,
C2C08EE72142748D00C69DBF /* conv2d_22.w_0 in Resources */,
C2C08EC02142748D00C69DBF /* batch_norm_28.w_0 in Resources */,
C2C08EC82142748D00C69DBF /* batch_norm_15.w_0 in Resources */,
C2C08F012142748D00C69DBF /* batch_norm_28.b_0 in Resources */,
C2C08E692142748D00C69DBF /* batch_norm_24.b_0 in Resources */,
C2C08E3B2142748D00C69DBF /* synset.txt in Resources */,
C2C08E892142748D00C69DBF /* batch_norm_22.w_1 in Resources */,
C2C08E772142748D00C69DBF /* batch_norm_0.w_0 in Resources */,
C2C08EA72142748D00C69DBF /* conv2d_9.w_0 in Resources */,
C2C08E9C2142748D00C69DBF /* batch_norm_32.w_1 in Resources */,
C2C08EA02142748D00C69DBF /* batch_norm_18.w_1 in Resources */,
C2C08F0E2142748D00C69DBF /* batch_norm_24.w_2 in Resources */,
C2C08EF42142748D00C69DBF /* conv2d_25.w_0 in Resources */,
C2C08E962142748D00C69DBF /* conv2d_28.b_0 in Resources */,
C2C08ED22142748D00C69DBF /* batch_norm_2.w_2 in Resources */,
C2C08ED62142748D00C69DBF /* depthwise_conv2d_10.w_0 in Resources */,
C2C08EBC2142748D00C69DBF /* batch_norm_17.w_1 in Resources */,
C2C08E862142748D00C69DBF /* batch_norm_2.b_0 in Resources */,
C2C08EF22142748D00C69DBF /* depthwise_conv2d_5.w_0 in Resources */,
C2C08EB02142748D00C69DBF /* batch_norm_5.w_2 in Resources */,
C23717882148E5A50092444E /* ar_model in Resources */,
C2C08E512142748D00C69DBF /* batch_norm_29.w_2 in Resources */,
C2C08E6E2142748D00C69DBF /* conv2d_10.w_0 in Resources */,
C2C08E8D2142748D00C69DBF /* batch_norm_34.w_0 in Resources */,
C2C08E642142748D00C69DBF /* batch_norm_6.w_1 in Resources */,
C2C08EAB2142748D00C69DBF /* batch_norm_19.w_1 in Resources */,
C2C08F002142748D00C69DBF /* conv2d_24.w_0 in Resources */,
C2C08EAD2142748D00C69DBF /* batch_norm_31.w_1 in Resources */,
C2C08EFA2142748D00C69DBF /* batch_norm_26.w_2 in Resources */,
C2C08F0D2142748D00C69DBF /* batch_norm_30.w_2 in Resources */,
C2C08E922142748D00C69DBF /* batch_norm_5.b_0 in Resources */,
C2C08E822142748D00C69DBF /* batch_norm_21.w_1 in Resources */,
C2C08ECE2142748D00C69DBF /* conv2d_2.w_0 in Resources */,
C2C08E7D2142748D00C69DBF /* batch_norm_0.w_1 in Resources */,
C2C08F0F2142748D00C69DBF /* batch_norm_18.w_2 in Resources */,
C2C08E682142748D00C69DBF /* conv2d_28.w_0 in Resources */,
C2C08E802142748D00C69DBF /* conv2d_12.w_0 in Resources */,
C2C08E752142748D00C69DBF /* batch_norm_21.b_0 in Resources */,
C2C08ED82142748D00C69DBF /* conv2d_22.b_0 in Resources */,
C2C08E552142748D00C69DBF /* batch_norm_14.w_2 in Resources */,
C2C08E6D2142748D00C69DBF /* batch_norm_1.w_0 in Resources */,
C2C08EF52142748D00C69DBF /* batch_norm_29.b_0 in Resources */,
C2C08E912142748D00C69DBF /* batch_norm_33.w_1 in Resources */,
C2C08F052142748D00C69DBF /* conv2d_32.w_0 in Resources */,
C2C08E732142748D00C69DBF /* batch_norm_3.w_1 in Resources */,
C2C08ED32142748D00C69DBF /* depthwise_conv2d_12.w_0 in Resources */,
C2C08F092142748D00C69DBF /* batch_norm_25.w_2 in Resources */,
C2C08E5F2142748D00C69DBF /* conv2d_15.w_0 in Resources */,
C2C08E5A2142748D00C69DBF /* batch_norm_4.w_0 in Resources */,
C2C08EDD2142748D00C69DBF /* conv2d_23.b_0 in Resources */,
C2C08E712142748D00C69DBF /* batch_norm_13.w_2 in Resources */,
C2C08EDE2142748D00C69DBF /* batch_norm_1.w_2 in Resources */,
C2C08EDA2142748D00C69DBF /* batch_norm_12.w_0 in Resources */,
C2C08E812142748D00C69DBF /* batch_norm_3.w_0 in Resources */,
C2C08EA42142748D00C69DBF /* batch_norm_27.w_0 in Resources */,
C2C08ECC2142748D00C69DBF /* batch_norm_12.w_1 in Resources */,
C2C08E592142748D00C69DBF /* batch_norm_6.w_0 in Resources */,
C2C08E3D2142748D00C69DBF /* hand.jpg in Resources */,
C2C08E422142748D00C69DBF /* genet_params in Resources */,
C2C08F122142748D00C69DBF /* conv2d_33.w_0 in Resources */,
C2C08F132142748D00C69DBF /* depthwise_conv2d_7.w_0 in Resources */,
FC039B8720E11C550081E9F8 /* Main.storyboard in Resources */, FC039B8720E11C550081E9F8 /* Main.storyboard in Resources */,
C2C08EFF2142748D00C69DBF /* conv2d_30.w_0 in Resources */, FCA3A16121313E1F00084FE5 /* hand.jpg in Resources */,
C2C08F062142748D00C69DBF /* conv2d_26.w_0 in Resources */, FC8CFEE62135452C0094D569 /* genet_params in Resources */,
FCBCCC532122EEDC00D94F7E /* ssd_hand_model in Resources */,
FC9A19E72148C38400CD9CBF /* ar_model in Resources */,
FC9A19E82148C38400CD9CBF /* ar_params in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -1188,8 +359,11 @@ ...@@ -1188,8 +359,11 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
FC039B8420E11C550081E9F8 /* ViewController.swift in Sources */, FC039B8420E11C550081E9F8 /* ViewController.swift in Sources */,
FC803BCE214D27930094B8E5 /* VideoCapture.swift in Sources */,
FC013928210204A3008100E3 /* PreProcessKernel.metal in Sources */, FC013928210204A3008100E3 /* PreProcessKernel.metal in Sources */,
FCF437E8214B6DDB00943429 /* MultiPredictViewController.swift in Sources */,
FCBCCC552122EF5500D94F7E /* MetalHelper.swift in Sources */, FCBCCC552122EF5500D94F7E /* MetalHelper.swift in Sources */,
FC803BCD214D27930094B8E5 /* FPSCounter.swift in Sources */,
FC039B8220E11C550081E9F8 /* AppDelegate.swift in Sources */, FC039B8220E11C550081E9F8 /* AppDelegate.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
...@@ -1338,10 +512,10 @@ ...@@ -1338,10 +512,10 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 6K8JTBT3MF; DEVELOPMENT_TEAM = A798K58VVL;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "paddle-mobile-demo/Info.plist"; INFOPLIST_FILE = "paddle-mobile-demo/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
...@@ -1365,10 +539,10 @@ ...@@ -1365,10 +539,10 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 6K8JTBT3MF; DEVELOPMENT_TEAM = A798K58VVL;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "paddle-mobile-demo/Info.plist"; INFOPLIST_FILE = "paddle-mobile-demo/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
......
...@@ -11,6 +11,34 @@ ...@@ -11,6 +11,34 @@
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
<!--Multi Predict View Controller-->
<scene sceneID="ec4-AW-9Vs">
<objects>
<viewController id="Vwd-lt-764" customClass="MultiPredictViewController" customModule="paddle_mobile_demo" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="55D-rz-Ex6">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TQt-X9-PdF">
<rect key="frame" x="164" y="318" width="46" height="30"/>
<state key="normal" title="Button"/>
<connections>
<action selector="predictAct:" destination="Vwd-lt-764" eventType="touchUpInside" id="d4z-Cv-6jY"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="TQt-X9-PdF" firstAttribute="centerY" secondItem="55D-rz-Ex6" secondAttribute="centerY" id="bL3-wr-TcH"/>
<constraint firstItem="TQt-X9-PdF" firstAttribute="centerX" secondItem="55D-rz-Ex6" secondAttribute="centerX" id="sBi-RQ-sJn"/>
</constraints>
<viewLayoutGuide key="safeArea" id="bsd-h4-RYZ"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="68E-SG-96s" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-559" y="686"/>
</scene>
<!--View Controller--> <!--View Controller-->
<scene sceneID="tne-QT-ifu"> <scene sceneID="tne-QT-ifu">
<objects> <objects>
...@@ -20,9 +48,9 @@ ...@@ -20,9 +48,9 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZZh-fw-LwK"> <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZZh-fw-LwK">
<rect key="frame" x="0.0" y="20" width="375" height="247"/> <rect key="frame" x="0.0" y="20" width="225" height="247"/>
</imageView> </imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Thread:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2EB-m2-a3L"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Platform:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2EB-m2-a3L">
<rect key="frame" x="10" y="538" width="68" height="24"/> <rect key="frame" x="10" y="538" width="68" height="24"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="68" id="Q5J-tq-JSX"/> <constraint firstAttribute="width" constant="68" id="Q5J-tq-JSX"/>
...@@ -142,9 +170,14 @@ ...@@ -142,9 +170,14 @@
<fontDescription key="fontDescription" type="system" pointSize="15"/> <fontDescription key="fontDescription" type="system" pointSize="15"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView> </textView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Cil-py-NiA">
<rect key="frame" x="225" y="20" width="150" height="247"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews> </subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstItem="m5L-O7-P31" firstAttribute="top" secondItem="Cil-py-NiA" secondAttribute="bottom" constant="10" id="16p-IK-b5X"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="VQn-bS-fWp" secondAttribute="trailing" constant="10" id="1Xg-0h-9SE"/> <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="VQn-bS-fWp" secondAttribute="trailing" constant="10" id="1Xg-0h-9SE"/>
<constraint firstItem="avL-VK-Kha" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="10" id="2t9-hS-VXa"/> <constraint firstItem="avL-VK-Kha" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="10" id="2t9-hS-VXa"/>
<constraint firstItem="R90-Yf-S6g" firstAttribute="centerY" secondItem="wUL-9N-u1V" secondAttribute="centerY" id="76b-Ny-1Og"/> <constraint firstItem="R90-Yf-S6g" firstAttribute="centerY" secondItem="wUL-9N-u1V" secondAttribute="centerY" id="76b-Ny-1Og"/>
...@@ -159,11 +192,12 @@ ...@@ -159,11 +192,12 @@
<constraint firstItem="XpL-9M-UOp" firstAttribute="centerY" secondItem="wUL-9N-u1V" secondAttribute="centerY" id="KWW-qT-Rzf"/> <constraint firstItem="XpL-9M-UOp" firstAttribute="centerY" secondItem="wUL-9N-u1V" secondAttribute="centerY" id="KWW-qT-Rzf"/>
<constraint firstItem="6MG-gv-hD5" firstAttribute="centerY" secondItem="avL-VK-Kha" secondAttribute="centerY" id="KZa-YZ-DEs"/> <constraint firstItem="6MG-gv-hD5" firstAttribute="centerY" secondItem="avL-VK-Kha" secondAttribute="centerY" id="KZa-YZ-DEs"/>
<constraint firstItem="2EB-m2-a3L" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="10" id="Le3-TN-zOL"/> <constraint firstItem="2EB-m2-a3L" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="10" id="Le3-TN-zOL"/>
<constraint firstItem="ZZh-fw-LwK" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="MeS-HQ-voE"/> <constraint firstItem="ZZh-fw-LwK" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" constant="-150" id="MeS-HQ-voE"/>
<constraint firstItem="m5L-O7-P31" firstAttribute="top" secondItem="ZZh-fw-LwK" secondAttribute="bottom" constant="10" id="NUL-Ta-VI8"/> <constraint firstItem="m5L-O7-P31" firstAttribute="top" secondItem="ZZh-fw-LwK" secondAttribute="bottom" constant="10" id="NUL-Ta-VI8"/>
<constraint firstItem="m5L-O7-P31" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="15" id="RFA-z1-9aB"/> <constraint firstItem="m5L-O7-P31" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="15" id="RFA-z1-9aB"/>
<constraint firstItem="wUL-9N-u1V" firstAttribute="width" secondItem="a3K-ri-NVs" secondAttribute="width" id="Rp6-Bh-BN3"/> <constraint firstItem="wUL-9N-u1V" firstAttribute="width" secondItem="a3K-ri-NVs" secondAttribute="width" id="Rp6-Bh-BN3"/>
<constraint firstItem="6MG-gv-hD5" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="S0W-0G-75m"/> <constraint firstItem="6MG-gv-hD5" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="S0W-0G-75m"/>
<constraint firstItem="Cil-py-NiA" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="UNc-Et-9Yv"/>
<constraint firstItem="w7H-Sk-Rai" firstAttribute="leading" secondItem="wUL-9N-u1V" secondAttribute="trailing" id="VBM-8b-jP0"/> <constraint firstItem="w7H-Sk-Rai" firstAttribute="leading" secondItem="wUL-9N-u1V" secondAttribute="trailing" id="VBM-8b-jP0"/>
<constraint firstItem="VQn-bS-fWp" firstAttribute="top" secondItem="m5L-O7-P31" secondAttribute="bottom" constant="8" id="VpS-4N-mOo"/> <constraint firstItem="VQn-bS-fWp" firstAttribute="top" secondItem="m5L-O7-P31" secondAttribute="bottom" constant="8" id="VpS-4N-mOo"/>
<constraint firstItem="wUL-9N-u1V" firstAttribute="top" secondItem="2EB-m2-a3L" secondAttribute="bottom" constant="35" id="VpU-j2-gaE"/> <constraint firstItem="wUL-9N-u1V" firstAttribute="top" secondItem="2EB-m2-a3L" secondAttribute="bottom" constant="35" id="VpU-j2-gaE"/>
...@@ -175,10 +209,12 @@ ...@@ -175,10 +209,12 @@
<constraint firstItem="ZZh-fw-LwK" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="eIC-fZ-OEE"/> <constraint firstItem="ZZh-fw-LwK" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="eIC-fZ-OEE"/>
<constraint firstItem="976-fk-Kx2" firstAttribute="centerY" secondItem="wUL-9N-u1V" secondAttribute="centerY" id="fFg-pB-eyU"/> <constraint firstItem="976-fk-Kx2" firstAttribute="centerY" secondItem="wUL-9N-u1V" secondAttribute="centerY" id="fFg-pB-eyU"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="wUL-9N-u1V" secondAttribute="bottom" constant="40" id="fG6-0p-I0P"/> <constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="wUL-9N-u1V" secondAttribute="bottom" constant="40" id="fG6-0p-I0P"/>
<constraint firstItem="Cil-py-NiA" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="gGK-DB-ibv"/>
<constraint firstItem="XpL-9M-UOp" firstAttribute="leading" secondItem="w7H-Sk-Rai" secondAttribute="trailing" id="guC-Db-cA9"/> <constraint firstItem="XpL-9M-UOp" firstAttribute="leading" secondItem="w7H-Sk-Rai" secondAttribute="trailing" id="guC-Db-cA9"/>
<constraint firstItem="6MG-gv-hD5" firstAttribute="leading" secondItem="avL-VK-Kha" secondAttribute="trailing" constant="10" id="jNW-iC-u7V"/> <constraint firstItem="6MG-gv-hD5" firstAttribute="leading" secondItem="avL-VK-Kha" secondAttribute="trailing" constant="10" id="jNW-iC-u7V"/>
<constraint firstItem="4ey-Xr-U4e" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="o1X-q5-P7j"/> <constraint firstItem="4ey-Xr-U4e" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="o1X-q5-P7j"/>
<constraint firstItem="6MG-gv-hD5" firstAttribute="top" secondItem="VQn-bS-fWp" secondAttribute="bottom" constant="8" id="tAE-ss-jlA"/> <constraint firstItem="6MG-gv-hD5" firstAttribute="top" secondItem="VQn-bS-fWp" secondAttribute="bottom" constant="8" id="tAE-ss-jlA"/>
<constraint firstItem="Cil-py-NiA" firstAttribute="leading" secondItem="ZZh-fw-LwK" secondAttribute="trailing" id="teJ-PP-h2R"/>
<constraint firstItem="4ey-Xr-U4e" firstAttribute="top" secondItem="wUL-9N-u1V" secondAttribute="bottom" constant="10" id="udc-wT-jqd"/> <constraint firstItem="4ey-Xr-U4e" firstAttribute="top" secondItem="wUL-9N-u1V" secondAttribute="bottom" constant="10" id="udc-wT-jqd"/>
<constraint firstItem="ZZh-fw-LwK" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="vXI-l2-CjL"/> <constraint firstItem="ZZh-fw-LwK" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="vXI-l2-CjL"/>
<constraint firstItem="VQn-bS-fWp" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="10" id="wtI-Dl-YPq"/> <constraint firstItem="VQn-bS-fWp" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="10" id="wtI-Dl-YPq"/>
...@@ -195,11 +231,12 @@ ...@@ -195,11 +231,12 @@
<outlet property="resultTextView" destination="VQn-bS-fWp" id="306-c7-3vM"/> <outlet property="resultTextView" destination="VQn-bS-fWp" id="306-c7-3vM"/>
<outlet property="selectImageView" destination="ZZh-fw-LwK" id="afR-Bv-6AW"/> <outlet property="selectImageView" destination="ZZh-fw-LwK" id="afR-Bv-6AW"/>
<outlet property="threadPickerView" destination="DlO-dk-RMr" id="Kk4-QV-b5o"/> <outlet property="threadPickerView" destination="DlO-dk-RMr" id="Kk4-QV-b5o"/>
<outlet property="videoView" destination="Cil-py-NiA" id="QY2-BP-SNS"/>
</connections> </connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="-724" y="98.50074962518741"/> <point key="canvasLocation" x="-1127" y="-3"/>
</scene> </scene>
</scenes> </scenes>
<resources> <resources>
......
//
// Multi-Predict-ViewController.swift
// paddle-mobile-demo
//
// Created by liuRuiLong on 2018/9/14.
// Copyright © 2018年 orange. All rights reserved.
//
import UIKit
import paddle_mobile
class MultiPredictViewController: UIViewController {
var runner1: Runner!
var runner2: Runner!
override func viewDidLoad() {
super.viewDidLoad()
let mobileNet = MobileNet_ssd_hand.init(device: MetalHelper.shared.device)
let genet = Genet.init(device: MetalHelper.shared.device)
runner1 = Runner.init(inNet: mobileNet, commandQueue: MetalHelper.shared.queue, inPlatform: .GPU)
let queue2 = MetalHelper.shared.device.makeCommandQueue()
runner2 = Runner.init(inNet: genet, commandQueue: MetalHelper.shared.queue, inPlatform: .GPU)
}
@IBAction func predictAct(_ sender: Any) {
let success = self.runner2.load()
// DispatchQueue.global().async {
let image1 = UIImage.init(named: "hand.jpg")
// let success = self.runner2.load()
// if success {
// for i in 0..<10000 {
// print(i)
// self.runner2.predict(cgImage: image1!.cgImage!, completion: { (success, res) in
// print("result1: ")
//// print(res)
// })
// }
// } else {
// print("load failed")
// }
// self.runner1.clear()
// }
// return
// DispatchQueue.global().async {
//// sleep(1)
// let image1 = UIImage.init(named: "banana.jpeg")
//// if success {
// for _ in 0..<10 {
// self.runner2.predict(cgImage: image1!.cgImage!, completion: { (success, res) in
// print("result2: ")
// print(res)
// })
// }
//// } else {
//// print("load failed")
//// }
//// self.runner2.clear()
// }
}
}
import Foundation
import QuartzCore
public class FPSCounter {
private(set) public var fps: Double = 0
var frames = 0
var startTime: CFTimeInterval = 0
public func start() {
frames = 0
startTime = CACurrentMediaTime()
}
public func frameCompleted() {
frames += 1
let now = CACurrentMediaTime()
let elapsed = now - startTime
if elapsed > 0.1 {
let current = Double(frames) / elapsed
let smoothing = 0.75
fps = smoothing*fps + (1 - smoothing)*current
if elapsed > 1 {
frames = 0
startTime = CACurrentMediaTime()
}
}
}
}
import UIKit
import Metal
import CoreVideo
import AVFoundation
@available(iOS 10.0, *)
@objc public protocol VideoCaptureDelegate: NSObjectProtocol {
@objc optional func videoCapture(_ capture: VideoCapture, didCaptureSampleBuffer sampleBuffer: CMSampleBuffer, timestamp: CMTime)
@objc optional func videoCapture(_ capture: VideoCapture, didCaptureVideoTexture texture: MTLTexture?, timestamp: CMTime)
@objc optional func videoCapture(_ capture: VideoCapture, didCapturePhoto previewImage: UIImage?)
@objc optional func videoCapture(_ capture: VideoCapture, didCapturePhotoTexture texture: MTLTexture?)
}
/**
Simple interface to the iPhone's camera.
*/
@available(iOS 10.0, *)
public class VideoCapture: NSObject {
public var previewLayer: AVCaptureVideoPreviewLayer?
public weak var delegate: VideoCaptureDelegate?
public var fps = -1
private let device: MTLDevice?
private let videoOrientation: AVCaptureVideoOrientation
private var textureCache: CVMetalTextureCache?
private let captureSession = AVCaptureSession()
private let videoOutput = AVCaptureVideoDataOutput()
private let photoOutput = AVCapturePhotoOutput()
private let queue = DispatchQueue(label: "net.machinethink.camera-queue")
private var lastTimestamp = CMTime()
private let cameraPosition: AVCaptureDevice.Position
public init(device: MTLDevice? = nil, orientation: AVCaptureVideoOrientation = .portrait, position: AVCaptureDevice.Position = .back) {
self.device = device
self.videoOrientation = orientation
self.cameraPosition = position
super.init()
}
public func setUp(sessionPreset: AVCaptureSession.Preset = .medium,
completion: @escaping (Bool) -> Void) {
queue.async {
let success = self.setUpCamera(sessionPreset: sessionPreset)
DispatchQueue.main.async {
completion(success)
}
}
}
func fontCamera() -> AVCaptureDevice? {
let deveices = AVCaptureDevice.DiscoverySession.init(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .front).devices
return deveices.first
}
func setUpCamera(sessionPreset: AVCaptureSession.Preset) -> Bool {
if let inDevice = device{
guard CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, inDevice, nil, &textureCache) == kCVReturnSuccess else {
print("Error: could not create a texture cache")
return false
}
}
captureSession.beginConfiguration()
captureSession.sessionPreset = sessionPreset
var oCaptureDevice: AVCaptureDevice?
switch cameraPosition {
case .back:
oCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video)
break
case .front:
oCaptureDevice = fontCamera()
break
default:
break
}
guard let captureDevice = oCaptureDevice else {
print("Error: no video devices available")
return false
}
guard let videoInput = try? AVCaptureDeviceInput(device: captureDevice) else {
print("Error: could not create AVCaptureDeviceInput")
return false
}
if captureSession.canAddInput(videoInput) {
captureSession.addInput(videoInput)
}
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspect
previewLayer.connection?.videoOrientation = self.videoOrientation
self.previewLayer = previewLayer
let settings: [String : Any] = [
kCVPixelBufferPixelFormatTypeKey as String: NSNumber(value: kCVPixelFormatType_32BGRA)
]
videoOutput.videoSettings = settings
videoOutput.alwaysDiscardsLateVideoFrames = true
videoOutput.setSampleBufferDelegate(self, queue: queue)
if captureSession.canAddOutput(videoOutput) {
captureSession.addOutput(videoOutput)
}
// We want the buffers to be in portrait orientation otherwise they are
// rotated by 90 degrees. Need to set this _after_ addOutput()!
videoOutput.connection(with: AVMediaType.video)?.videoOrientation = self.videoOrientation
if captureSession.canAddOutput(photoOutput) {
captureSession.addOutput(photoOutput)
}
captureSession.commitConfiguration()
return true
}
public func start() {
if !captureSession.isRunning {
captureSession.startRunning()
}
}
public func stop() {
if captureSession.isRunning {
captureSession.stopRunning()
}
}
/* Captures a single frame of the camera input. */
public func capturePhoto() {
let settings = AVCapturePhotoSettings(format: [kCVPixelBufferPixelFormatTypeKey as String: NSNumber(value: kCVPixelFormatType_32BGRA)])
settings.previewPhotoFormat = [
kCVPixelBufferPixelFormatTypeKey as String: settings.__availablePreviewPhotoPixelFormatTypes[0],
kCVPixelBufferWidthKey as String: 480,
kCVPixelBufferHeightKey as String: 360,
]
photoOutput.capturePhoto(with: settings, delegate: self)
}
func convertToMTLTexture(sampleBuffer: CMSampleBuffer?) -> MTLTexture? {
if let textureCache = textureCache, let sampleBuffer = sampleBuffer, let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)
var texture: CVMetalTexture?
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, imageBuffer, nil, .bgra8Unorm, width, height, 0, &texture)
if let texture = texture {
return CVMetalTextureGetTexture(texture)
}
}
return nil
}
func convertToUIImage(sampleBuffer: CMSampleBuffer?) -> UIImage? {
if let sampleBuffer = sampleBuffer,
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)
let rect = CGRect(x: 0, y: 0, width: CGFloat(width), height: CGFloat(height))
let ciImage = CIImage(cvPixelBuffer: imageBuffer)
let ciContext = CIContext(options: nil)
if let cgImage = ciContext.createCGImage(ciImage, from: rect) {
return UIImage(cgImage: cgImage)
}
}
return nil
}
}
extension VideoCapture: AVCaptureVideoDataOutputSampleBufferDelegate {
public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// Because lowering the capture device's FPS looks ugly in the preview,
// we capture at full speed but only call the delegate at its desired
// framerate. If `fps` is -1, we run at the full framerate.
let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
let deltaTime = timestamp - lastTimestamp
if fps == -1 || deltaTime >= CMTimeMake(1, Int32(fps)) {
lastTimestamp = timestamp
self.delegate?.videoCapture?(self, didCaptureSampleBuffer: sampleBuffer, timestamp: timestamp)
if self.delegate?.responds(to: #selector(VideoCaptureDelegate.videoCapture(_:didCaptureVideoTexture:timestamp:))) ?? false{
let texture = convertToMTLTexture(sampleBuffer: sampleBuffer)
delegate?.videoCapture?(self, didCaptureVideoTexture: texture, timestamp: timestamp)
}
}
}
public func captureOutput(_ output: AVCaptureOutput, didDrop sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
print("dropped frame")
}
}
extension VideoCapture: AVCapturePhotoCaptureDelegate {
public func photoOutput(_ captureOutput: AVCapturePhotoOutput,
didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?,
previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
resolvedSettings: AVCaptureResolvedPhotoSettings,
bracketSettings: AVCaptureBracketedStillImageSettings?,
error: Error?) {
var imageTexture: MTLTexture?
var previewImage: UIImage?
if error == nil {
if self.delegate?.responds(to: #selector(VideoCaptureDelegate.videoCapture(_:didCapturePhotoTexture:))) ?? false{
imageTexture = convertToMTLTexture(sampleBuffer: photoSampleBuffer)
self.delegate?.videoCapture?(self, didCapturePhotoTexture: imageTexture)
}
if self.delegate?.responds(to: #selector(VideoCaptureDelegate.videoCapture(_:didCapturePhoto:))) ?? false{
previewImage = convertToUIImage(sampleBuffer: previewPhotoSampleBuffer)
self.delegate?.videoCapture?(self, didCapturePhoto: previewImage)
}
}
}
}
...@@ -14,27 +14,32 @@ ...@@ -14,27 +14,32 @@
import UIKit import UIKit
import MetalKit import MetalKit
import CoreMedia
import paddle_mobile import paddle_mobile
import MetalPerformanceShaders import MetalPerformanceShaders
let platform: Platform = .GPU var platform: Platform = .GPU
let threadSupport = [1] let threadSupport: [(Platform, String)] = [(.GPU, "GPU"), (.CPU, "CPU")]
let modelHelperMap: [SupportModel : Runner] = [.mobilenet_ssd : Runner.init(inNet: MobileNet_ssd_hand.init(device: MetalHelper.shared.device), commandQueue: MetalHelper.shared.queue, inPlatform: platform), //.mobilenet_ssd : Runner.init(inNet: MobileNet_ssd_hand.init(device: MetalHelper.shared.device), commandQueue: MetalHelper.shared.queue, inPlatform: platform),
let modelHelperMap: [SupportModel : Runner] = [
.genet : Runner.init(inNet: Genet.init(device: MetalHelper.shared.device), commandQueue: MetalHelper.shared.queue, inPlatform: platform), .genet : Runner.init(inNet: Genet.init(device: MetalHelper.shared.device), commandQueue: MetalHelper.shared.queue, inPlatform: platform),
.mobilenet_ssd_ar : Runner.init(inNet: MobileNet_ssd_AR.init(device: MetalHelper.shared.device), commandQueue: MetalHelper.shared.queue, inPlatform: platform)] .mobilenet_ssd_ar : Runner.init(inNet: MobileNet_ssd_AR.init(device: MetalHelper.shared.device), commandQueue: MetalHelper.shared.queue, inPlatform: platform)]
//, .genet : Genet.init() //, .genet : Genet.init()
//let modelHelperMap: [SupportModel : Net] = [.mobilenet : MobileNet.init(), .mobilenet_ssd : MobileNet_ssd_hand.init()] //let modelHelperMap: [SupportModel : Net] = [.mobilenet : MobileNet.init(), .mobilenet_ssd : MobileNet_ssd_hand.init()]
let netSupport: [SupportModel : Net] = [.genet : Genet.init(device: MetalHelper.shared.device), .mobilenet_ssd_ar : MobileNet_ssd_AR.init(device: MetalHelper.shared.device)]
enum SupportModel: String{ enum SupportModel: String{
// case mobilenet = "mobilenet" // case mobilenet = "mobilenet"
case mobilenet_ssd = "mobilenetssd" // case mobilenet_ssd = "mobilenetssd"
case genet = "genet" case genet = "genet"
case mobilenet_ssd_ar = "mobilenetssd_ar" case mobilenet_ssd_ar = "mobilenetssd_ar"
static func supportedModels() -> [SupportModel] { static func supportedModels() -> [SupportModel] {
//.mobilenet, // .mobilenet,
return [.mobilenet_ssd, .genet, .mobilenet_ssd_ar] // .mobilenet_ssd,
return [.genet, .mobilenet_ssd_ar]
} }
} }
...@@ -44,24 +49,36 @@ class ViewController: UIViewController { ...@@ -44,24 +49,36 @@ class ViewController: UIViewController {
@IBOutlet weak var elapsedTimeLabel: UILabel! @IBOutlet weak var elapsedTimeLabel: UILabel!
@IBOutlet weak var modelPickerView: UIPickerView! @IBOutlet weak var modelPickerView: UIPickerView!
@IBOutlet weak var threadPickerView: UIPickerView! @IBOutlet weak var threadPickerView: UIPickerView!
@IBOutlet weak var videoView: UIView!
var videoCapture: VideoCapture!
var selectImage: UIImage? var selectImage: UIImage?
var inputPointer: UnsafeMutablePointer<Float32>? var inputPointer: UnsafeMutablePointer<Float32>?
var modelType: SupportModel = SupportModel.supportedModels()[0] var modelType: SupportModel = SupportModel.supportedModels()[0]
var toPredictTexture: MTLTexture? var toPredictTexture: MTLTexture?
var runner: Runner { var runner: Runner!
var threadNum = 1
@IBAction func loadAct(_ sender: Any) {
runner = Runner.init(inNet: netSupport[modelType]!, commandQueue: MetalHelper.shared.queue, inPlatform: platform)
if platform == .CPU {
if inputPointer == nil {
inputPointer = runner.preproccess(image: selectImage!.cgImage!)
get {
return modelHelperMap[modelType] ?! " has no this type "
} }
set { } else if platform == .GPU {
if self.toPredictTexture == nil {
runner.getTexture(image: selectImage!.cgImage!) {[weak self] (texture) in
self?.toPredictTexture = texture
} }
} }
} else {
fatalError( " unsupport " )
}
var threadNum = 1
@IBAction func loadAct(_ sender: Any) {
if runner.load() { if runner.load() {
print(" load success ! ") print(" load success ! ")
} else { } else {
...@@ -81,7 +98,7 @@ class ViewController: UIViewController { ...@@ -81,7 +98,7 @@ class ViewController: UIViewController {
} }
@IBAction func predictAct(_ sender: Any) { @IBAction func predictAct(_ sender: Any) {
let max = 1 let max = 50
switch platform { switch platform {
case .GPU: case .GPU:
guard let inTexture = toPredictTexture else { guard let inTexture = toPredictTexture else {
...@@ -91,7 +108,7 @@ class ViewController: UIViewController { ...@@ -91,7 +108,7 @@ class ViewController: UIViewController {
let startDate = Date.init() let startDate = Date.init()
for i in 0..<max { for i in 0..<max {
runner.predict(texture: inTexture) { [weak self] (success, res) in runner.predict(texture: inTexture) { [weak self] (success, resultHolder) in
guard let sSelf = self else { guard let sSelf = self else {
fatalError() fatalError()
} }
...@@ -99,11 +116,19 @@ class ViewController: UIViewController { ...@@ -99,11 +116,19 @@ class ViewController: UIViewController {
if i == max - 1 { if i == max - 1 {
let time = Date.init().timeIntervalSince(startDate) let time = Date.init().timeIntervalSince(startDate)
DispatchQueue.main.async { DispatchQueue.main.async {
sSelf.resultTextView.text = sSelf.runner.net.resultStr(res: res) // print(resultHolder!.result![0])
sSelf.resultTextView.text = sSelf.runner.net.resultStr(res: resultHolder!)
sSelf.elapsedTimeLabel.text = "平均耗时: \(time/Double(max) * 1000.0) ms" sSelf.elapsedTimeLabel.text = "平均耗时: \(time/Double(max) * 1000.0) ms"
} }
} }
} }
DispatchQueue.main.async {
resultHolder?.releasePointer()
}
// print("释放")
} }
// print("sleep before ") // print("sleep before ")
// usleep(33000) // usleep(33000)
...@@ -116,6 +141,7 @@ class ViewController: UIViewController { ...@@ -116,6 +141,7 @@ class ViewController: UIViewController {
for _ in 0..<10 { for _ in 0..<10 {
runner.predict(inputPointer: inInputPointer) { (success, res) in runner.predict(inputPointer: inInputPointer) { (success, res) in
res?.releaseOutput()
} }
} }
...@@ -129,11 +155,12 @@ class ViewController: UIViewController { ...@@ -129,11 +155,12 @@ class ViewController: UIViewController {
if i == max - 1 { if i == max - 1 {
let time = Date.init().timeIntervalSince(startDate) let time = Date.init().timeIntervalSince(startDate)
DispatchQueue.main.async { DispatchQueue.main.async {
sSelf.resultTextView.text = sSelf.runner.net.resultStr(res: res) // sSelf.resultTextView.text = sSelf.runner.net.resultStr(res: res)
sSelf.elapsedTimeLabel.text = "平均耗时: \(time/Double(max) * 1000.0) ms" sSelf.elapsedTimeLabel.text = "平均耗时: \(time/Double(max) * 1000.0) ms"
} }
} }
} }
res?.releaseOutput()
} }
} }
} }
...@@ -141,6 +168,13 @@ class ViewController: UIViewController { ...@@ -141,6 +168,13 @@ class ViewController: UIViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// if runner.load() {
// print(" load success ! ")
// } else {
// print(" load error ! ")
// }
//
modelPickerView.delegate = self modelPickerView.delegate = self
modelPickerView.dataSource = self modelPickerView.dataSource = self
threadPickerView.delegate = self threadPickerView.delegate = self
...@@ -149,15 +183,29 @@ class ViewController: UIViewController { ...@@ -149,15 +183,29 @@ class ViewController: UIViewController {
selectImage = UIImage.init(named: "hand.jpg") selectImage = UIImage.init(named: "hand.jpg")
selectImageView.image = selectImage selectImageView.image = selectImage
if platform == .CPU { // if platform == .CPU {
inputPointer = runner.preproccess(image: selectImage!.cgImage!) // inputPointer = runner.preproccess(image: selectImage!.cgImage!)
} else if platform == .GPU { // } else if platform == .GPU {
runner.getTexture(image: selectImage!.cgImage!) {[weak self] (texture) in // runner.getTexture(image: selectImage!.cgImage!) {[weak self] (texture) in
self?.toPredictTexture = texture // self?.toPredictTexture = texture
} // }
} else { // } else {
fatalError( " unsupport " ) // fatalError( " unsupport " )
} // }
// videoCapture = VideoCapture.init(device: MetalHelper.shared.device, orientation: .portrait, position: .back)
// videoCapture.fps = 30
// videoCapture.delegate = self
// videoCapture.setUp { (success) in
// DispatchQueue.main.async {
// if let preViewLayer = self.videoCapture.previewLayer {
// self.videoView.layer.addSublayer(preViewLayer)
// self.videoCapture.previewLayer?.frame = self.videoView.bounds
// }
// self.videoCapture.start()
// }
// }
} }
} }
...@@ -186,7 +234,7 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{ ...@@ -186,7 +234,7 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{
if pickerView == modelPickerView { if pickerView == modelPickerView {
return SupportModel.supportedModels()[row].rawValue return SupportModel.supportedModels()[row].rawValue
} else if pickerView == threadPickerView { } else if pickerView == threadPickerView {
return "\(threadSupport[row])" return threadSupport[row].1
} else { } else {
fatalError() fatalError()
} }
...@@ -196,7 +244,8 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{ ...@@ -196,7 +244,8 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate{
if pickerView == modelPickerView { if pickerView == modelPickerView {
self.modelType = SupportModel.supportedModels()[row] self.modelType = SupportModel.supportedModels()[row]
} else if pickerView == threadPickerView { } else if pickerView == threadPickerView {
self.threadNum = threadSupport[row]
platform = threadSupport[row].0
} else { } else {
fatalError() fatalError()
} }
...@@ -218,4 +267,32 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll ...@@ -218,4 +267,32 @@ extension ViewController: UIImagePickerControllerDelegate, UINavigationControll
} }
} }
var bool1 = false
extension ViewController: VideoCaptureDelegate{
func predictTexture(texture: MTLTexture){
runner.scaleTexture(input: texture) { (scaledTexture) in
self.runner.predict(texture: scaledTexture, completion: { (success, resultHolder) in
// print(resultHolder!.result![0])
resultHolder?.releasePointer()
})
}
}
func videoCapture(_ capture: VideoCapture, didCaptureVideoTexture texture: MTLTexture?, timestamp: CMTime) {
// if !bool1 {
// DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: 500000000)) {
self.predictTexture(texture: texture!)
// }
// bool1 = true
// }
}
}
...@@ -16,9 +16,18 @@ ...@@ -16,9 +16,18 @@
4AA1EA92214665D700D0F791 /* ShapeOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EA91214665D700D0F791 /* ShapeOp.swift */; }; 4AA1EA92214665D700D0F791 /* ShapeOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EA91214665D700D0F791 /* ShapeOp.swift */; };
4AA1EA942146661500D0F791 /* ShapeKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EA932146661500D0F791 /* ShapeKernel.swift */; }; 4AA1EA942146661500D0F791 /* ShapeKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EA932146661500D0F791 /* ShapeKernel.swift */; };
4AA1EA982146666500D0F791 /* FlattenOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EA972146666500D0F791 /* FlattenOp.swift */; }; 4AA1EA982146666500D0F791 /* FlattenOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EA972146666500D0F791 /* FlattenOp.swift */; };
4AA1EA9E2148D6F900D0F791 /* ConcatKernel.inc.metal in Headers */ = {isa = PBXBuildFile; fileRef = 4AA1EA9D2148D6F900D0F791 /* ConcatKernel.inc.metal */; };
4AA1EAA02148DEEE00D0F791 /* ReshapeKernel.inc.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EA9F2148DEEE00D0F791 /* ReshapeKernel.inc.metal */; };
4AA1EAA2214912CD00D0F791 /* FlattenKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */; };
4AA1EAA4214A295C00D0F791 /* Split.inc.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAA3214A295C00D0F791 /* Split.inc.metal */; };
4AA1EAA6214B5F6800D0F791 /* Shape.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAA5214B5F6800D0F791 /* Shape.metal */; };
4AA1EAA8214B7AFB00D0F791 /* BilinearInterp.inc.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAA7214B7AFB00D0F791 /* BilinearInterp.inc.metal */; };
4AA1EAAA214F53D800D0F791 /* BoxCoder.inc.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAA9214F53D800D0F791 /* BoxCoder.inc.metal */; };
4AA1EAAC214F55C800D0F791 /* Softmax.inc.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAAB214F55C800D0F791 /* Softmax.inc.metal */; };
4AA1EAAE214F5FD900D0F791 /* TransposeKernel.inc.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AA1EAAD214F5FD900D0F791 /* TransposeKernel.inc.metal */; };
4AF928772133F1DB005B6C3A /* BoxCoder.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AF928762133F1DB005B6C3A /* BoxCoder.metal */; }; 4AF928772133F1DB005B6C3A /* BoxCoder.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AF928762133F1DB005B6C3A /* BoxCoder.metal */; };
4AF9287921341661005B6C3A /* Softmax.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AF9287821341661005B6C3A /* Softmax.metal */; }; 4AF9287921341661005B6C3A /* Softmax.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AF9287821341661005B6C3A /* Softmax.metal */; };
4AF928822135673D005B6C3A /* Concat.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AF928812135673D005B6C3A /* Concat.metal */; }; 4AF928822135673D005B6C3A /* ConcatKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AF928812135673D005B6C3A /* ConcatKernel.metal */; };
4AF9288421357BE3005B6C3A /* Elementwise.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AF9288321357BE3005B6C3A /* Elementwise.metal */; }; 4AF9288421357BE3005B6C3A /* Elementwise.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4AF9288321357BE3005B6C3A /* Elementwise.metal */; };
D3831F70E7E0B565B9AC22DA /* Pods_paddle_mobile.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD2E06330A1E7129C918DB46 /* Pods_paddle_mobile.framework */; }; D3831F70E7E0B565B9AC22DA /* Pods_paddle_mobile.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD2E06330A1E7129C918DB46 /* Pods_paddle_mobile.framework */; };
FC0226562138F33800F395E2 /* TransposeKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FC0226552138F33800F395E2 /* TransposeKernel.metal */; }; FC0226562138F33800F395E2 /* TransposeKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FC0226552138F33800F395E2 /* TransposeKernel.metal */; };
...@@ -66,6 +75,12 @@ ...@@ -66,6 +75,12 @@
FC4FD97E2140F2C30073E130 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = FC4FD97D2140F2C30073E130 /* libstdc++.tbd */; }; FC4FD97E2140F2C30073E130 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = FC4FD97D2140F2C30073E130 /* libstdc++.tbd */; };
FC5163F620EF556E00636C28 /* Texture2DTo2DArrayKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5163F520EF556E00636C28 /* Texture2DTo2DArrayKernel.swift */; }; FC5163F620EF556E00636C28 /* Texture2DTo2DArrayKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5163F520EF556E00636C28 /* Texture2DTo2DArrayKernel.swift */; };
FC60DB8920E9AAA500FF203F /* MetalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC60DB8820E9AAA500FF203F /* MetalExtension.swift */; }; FC60DB8920E9AAA500FF203F /* MetalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC60DB8820E9AAA500FF203F /* MetalExtension.swift */; };
FC803BBF214CB65A0094B8E5 /* ConvAddPreluOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC803BBE214CB65A0094B8E5 /* ConvAddPreluOp.swift */; };
FC803BC1214CB77A0094B8E5 /* ConvAddPreluKernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC803BC0214CB77A0094B8E5 /* ConvAddPreluKernel.swift */; };
FC803BC3214CB79C0094B8E5 /* ConvAddPreluKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FC803BC2214CB79C0094B8E5 /* ConvAddPreluKernel.metal */; };
FC803BC5214CB8F00094B8E5 /* ConvAddPrelu.inc.metal in Sources */ = {isa = PBXBuildFile; fileRef = FC803BC4214CB8F00094B8E5 /* ConvAddPrelu.inc.metal */; };
FC803BC7214CBA820094B8E5 /* Macro.metal in Sources */ = {isa = PBXBuildFile; fileRef = FC803BC6214CBA820094B8E5 /* Macro.metal */; };
FC803BC9214CFC8D0094B8E5 /* FetchKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FC803BC8214CFC8D0094B8E5 /* FetchKernel.metal */; };
FC82735920E3C04200BE430A /* OpCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC82735820E3C04200BE430A /* OpCreator.swift */; }; FC82735920E3C04200BE430A /* OpCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC82735820E3C04200BE430A /* OpCreator.swift */; };
FC9A19E32148C31300CD9CBF /* MobilenetSSD_AR.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC9A19E22148C31300CD9CBF /* MobilenetSSD_AR.swift */; }; FC9A19E32148C31300CD9CBF /* MobilenetSSD_AR.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC9A19E22148C31300CD9CBF /* MobilenetSSD_AR.swift */; };
FC9D037920E229E4000F735A /* OpParam.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC9D037820E229E4000F735A /* OpParam.swift */; }; FC9D037920E229E4000F735A /* OpParam.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC9D037820E229E4000F735A /* OpParam.swift */; };
...@@ -107,6 +122,8 @@ ...@@ -107,6 +122,8 @@
FCDDC6CC212FDFDB00E5EF74 /* ReluKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FCDDC6CB212FDFDB00E5EF74 /* ReluKernel.metal */; }; FCDDC6CC212FDFDB00E5EF74 /* ReluKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FCDDC6CB212FDFDB00E5EF74 /* ReluKernel.metal */; };
FCDDC6CF212FE14700E5EF74 /* PriorBoxKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FCDDC6CE212FE14700E5EF74 /* PriorBoxKernel.metal */; }; FCDDC6CF212FE14700E5EF74 /* PriorBoxKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FCDDC6CE212FE14700E5EF74 /* PriorBoxKernel.metal */; };
FCDE8A33212A917900F4A8F6 /* ConvTransposeOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCDE8A32212A917900F4A8F6 /* ConvTransposeOp.swift */; }; FCDE8A33212A917900F4A8F6 /* ConvTransposeOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCDE8A32212A917900F4A8F6 /* ConvTransposeOp.swift */; };
FCE9D7B7214F869000B520C3 /* Net.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE9D7B6214F869000B520C3 /* Net.swift */; };
FCE9D7B9214FAA4800B520C3 /* NMSFetchResultKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FCE9D7B8214FAA4800B520C3 /* NMSFetchResultKernel.metal */; };
FCEB684A212F00DB00D2448E /* PreluKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FCEB6849212F00DB00D2448E /* PreluKernel.metal */; }; FCEB684A212F00DB00D2448E /* PreluKernel.metal in Sources */ = {isa = PBXBuildFile; fileRef = FCEB6849212F00DB00D2448E /* PreluKernel.metal */; };
FCEB684C212F093800D2448E /* PreluOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEB684B212F093800D2448E /* PreluOp.swift */; }; FCEB684C212F093800D2448E /* PreluOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEB684B212F093800D2448E /* PreluOp.swift */; };
FCEBC0F420F1FDD90099DBAF /* ConvAddBatchNormReluOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEBC0F320F1FDD90099DBAF /* ConvAddBatchNormReluOp.swift */; }; FCEBC0F420F1FDD90099DBAF /* ConvAddBatchNormReluOp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEBC0F320F1FDD90099DBAF /* ConvAddBatchNormReluOp.swift */; };
...@@ -124,9 +141,18 @@ ...@@ -124,9 +141,18 @@
4AA1EA91214665D700D0F791 /* ShapeOp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShapeOp.swift; sourceTree = "<group>"; }; 4AA1EA91214665D700D0F791 /* ShapeOp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShapeOp.swift; sourceTree = "<group>"; };
4AA1EA932146661500D0F791 /* ShapeKernel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShapeKernel.swift; sourceTree = "<group>"; }; 4AA1EA932146661500D0F791 /* ShapeKernel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShapeKernel.swift; sourceTree = "<group>"; };
4AA1EA972146666500D0F791 /* FlattenOp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlattenOp.swift; sourceTree = "<group>"; }; 4AA1EA972146666500D0F791 /* FlattenOp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlattenOp.swift; sourceTree = "<group>"; };
4AA1EA9D2148D6F900D0F791 /* ConcatKernel.inc.metal */ = {isa = PBXFileReference; explicitFileType = sourcecode.metal; fileEncoding = 4; path = ConcatKernel.inc.metal; sourceTree = "<group>"; };
4AA1EA9F2148DEEE00D0F791 /* ReshapeKernel.inc.metal */ = {isa = PBXFileReference; explicitFileType = sourcecode.metal; fileEncoding = 4; path = ReshapeKernel.inc.metal; sourceTree = "<group>"; };
4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlattenKernel.swift; sourceTree = "<group>"; };
4AA1EAA3214A295C00D0F791 /* Split.inc.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Split.inc.metal; sourceTree = "<group>"; };
4AA1EAA5214B5F6800D0F791 /* Shape.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Shape.metal; sourceTree = "<group>"; };
4AA1EAA7214B7AFB00D0F791 /* BilinearInterp.inc.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = BilinearInterp.inc.metal; sourceTree = "<group>"; };
4AA1EAA9214F53D800D0F791 /* BoxCoder.inc.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = BoxCoder.inc.metal; sourceTree = "<group>"; };
4AA1EAAB214F55C800D0F791 /* Softmax.inc.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Softmax.inc.metal; sourceTree = "<group>"; };
4AA1EAAD214F5FD900D0F791 /* TransposeKernel.inc.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = TransposeKernel.inc.metal; sourceTree = "<group>"; };
4AF928762133F1DB005B6C3A /* BoxCoder.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = BoxCoder.metal; sourceTree = "<group>"; }; 4AF928762133F1DB005B6C3A /* BoxCoder.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = BoxCoder.metal; sourceTree = "<group>"; };
4AF9287821341661005B6C3A /* Softmax.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Softmax.metal; sourceTree = "<group>"; }; 4AF9287821341661005B6C3A /* Softmax.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Softmax.metal; sourceTree = "<group>"; };
4AF928812135673D005B6C3A /* Concat.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Concat.metal; sourceTree = "<group>"; }; 4AF928812135673D005B6C3A /* ConcatKernel.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = ConcatKernel.metal; sourceTree = "<group>"; };
4AF9288321357BE3005B6C3A /* Elementwise.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Elementwise.metal; sourceTree = "<group>"; }; 4AF9288321357BE3005B6C3A /* Elementwise.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Elementwise.metal; sourceTree = "<group>"; };
CDF58151D902A1CBAE56A0C2 /* Pods-paddle-mobile.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-paddle-mobile.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-paddle-mobile/Pods-paddle-mobile.debug.xcconfig"; sourceTree = "<group>"; }; CDF58151D902A1CBAE56A0C2 /* Pods-paddle-mobile.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-paddle-mobile.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-paddle-mobile/Pods-paddle-mobile.debug.xcconfig"; sourceTree = "<group>"; };
DD2E06330A1E7129C918DB46 /* Pods_paddle_mobile.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_paddle_mobile.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DD2E06330A1E7129C918DB46 /* Pods_paddle_mobile.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_paddle_mobile.framework; sourceTree = BUILT_PRODUCTS_DIR; };
...@@ -162,7 +188,6 @@ ...@@ -162,7 +188,6 @@
FC0E2DBD20EE460D009C1FAC /* BatchNormKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchNormKernel.swift; sourceTree = "<group>"; }; FC0E2DBD20EE460D009C1FAC /* BatchNormKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchNormKernel.swift; sourceTree = "<group>"; };
FC0E2DBF20EE461F009C1FAC /* ElementwiseAddKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementwiseAddKernel.swift; sourceTree = "<group>"; }; FC0E2DBF20EE461F009C1FAC /* ElementwiseAddKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementwiseAddKernel.swift; sourceTree = "<group>"; };
FC1B16B220EC9A4F00678B91 /* Kernels.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Kernels.metal; sourceTree = "<group>"; }; FC1B16B220EC9A4F00678B91 /* Kernels.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Kernels.metal; sourceTree = "<group>"; };
FC27990D21341016000B6BAD /* BoxCoder.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = BoxCoder.metal; sourceTree = "<group>"; };
FC292C5321421B2E00CF622F /* PaddleMobileGPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PaddleMobileGPU.h; sourceTree = "<group>"; }; FC292C5321421B2E00CF622F /* PaddleMobileGPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PaddleMobileGPU.h; sourceTree = "<group>"; };
FC292C5521421B4600CF622F /* PaddleMobileGPU.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PaddleMobileGPU.m; sourceTree = "<group>"; }; FC292C5521421B4600CF622F /* PaddleMobileGPU.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PaddleMobileGPU.m; sourceTree = "<group>"; };
FC292C7C214255BC00CF622F /* CPUCompute.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CPUCompute.mm; sourceTree = "<group>"; }; FC292C7C214255BC00CF622F /* CPUCompute.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CPUCompute.mm; sourceTree = "<group>"; };
...@@ -179,6 +204,12 @@ ...@@ -179,6 +204,12 @@
FC4FD97D2140F2C30073E130 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; }; FC4FD97D2140F2C30073E130 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
FC5163F520EF556E00636C28 /* Texture2DTo2DArrayKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Texture2DTo2DArrayKernel.swift; sourceTree = "<group>"; }; FC5163F520EF556E00636C28 /* Texture2DTo2DArrayKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Texture2DTo2DArrayKernel.swift; sourceTree = "<group>"; };
FC60DB8820E9AAA500FF203F /* MetalExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetalExtension.swift; sourceTree = "<group>"; }; FC60DB8820E9AAA500FF203F /* MetalExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetalExtension.swift; sourceTree = "<group>"; };
FC803BBE214CB65A0094B8E5 /* ConvAddPreluOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConvAddPreluOp.swift; sourceTree = "<group>"; };
FC803BC0214CB77A0094B8E5 /* ConvAddPreluKernel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConvAddPreluKernel.swift; sourceTree = "<group>"; };
FC803BC2214CB79C0094B8E5 /* ConvAddPreluKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = ConvAddPreluKernel.metal; sourceTree = "<group>"; };
FC803BC4214CB8F00094B8E5 /* ConvAddPrelu.inc.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = ConvAddPrelu.inc.metal; sourceTree = "<group>"; };
FC803BC6214CBA820094B8E5 /* Macro.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Macro.metal; sourceTree = "<group>"; };
FC803BC8214CFC8D0094B8E5 /* FetchKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = FetchKernel.metal; sourceTree = "<group>"; };
FC82735820E3C04200BE430A /* OpCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpCreator.swift; sourceTree = "<group>"; }; FC82735820E3C04200BE430A /* OpCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpCreator.swift; sourceTree = "<group>"; };
FC9A19E22148C31300CD9CBF /* MobilenetSSD_AR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobilenetSSD_AR.swift; sourceTree = "<group>"; }; FC9A19E22148C31300CD9CBF /* MobilenetSSD_AR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobilenetSSD_AR.swift; sourceTree = "<group>"; };
FC9D037820E229E4000F735A /* OpParam.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpParam.swift; sourceTree = "<group>"; }; FC9D037820E229E4000F735A /* OpParam.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpParam.swift; sourceTree = "<group>"; };
...@@ -220,6 +251,8 @@ ...@@ -220,6 +251,8 @@
FCDDC6CB212FDFDB00E5EF74 /* ReluKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = ReluKernel.metal; sourceTree = "<group>"; }; FCDDC6CB212FDFDB00E5EF74 /* ReluKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = ReluKernel.metal; sourceTree = "<group>"; };
FCDDC6CE212FE14700E5EF74 /* PriorBoxKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = PriorBoxKernel.metal; sourceTree = "<group>"; }; FCDDC6CE212FE14700E5EF74 /* PriorBoxKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = PriorBoxKernel.metal; sourceTree = "<group>"; };
FCDE8A32212A917900F4A8F6 /* ConvTransposeOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConvTransposeOp.swift; sourceTree = "<group>"; }; FCDE8A32212A917900F4A8F6 /* ConvTransposeOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConvTransposeOp.swift; sourceTree = "<group>"; };
FCE9D7B6214F869000B520C3 /* Net.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Net.swift; sourceTree = "<group>"; };
FCE9D7B8214FAA4800B520C3 /* NMSFetchResultKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = NMSFetchResultKernel.metal; sourceTree = "<group>"; };
FCEB6849212F00DB00D2448E /* PreluKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = PreluKernel.metal; sourceTree = "<group>"; }; FCEB6849212F00DB00D2448E /* PreluKernel.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = PreluKernel.metal; sourceTree = "<group>"; };
FCEB684B212F093800D2448E /* PreluOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreluOp.swift; sourceTree = "<group>"; }; FCEB684B212F093800D2448E /* PreluOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreluOp.swift; sourceTree = "<group>"; };
FCEBC0F320F1FDD90099DBAF /* ConvAddBatchNormReluOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ConvAddBatchNormReluOp.swift; path = "paddle-mobile/Operators/ConvAddBatchNormReluOp.swift"; sourceTree = SOURCE_ROOT; }; FCEBC0F320F1FDD90099DBAF /* ConvAddBatchNormReluOp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ConvAddBatchNormReluOp.swift; path = "paddle-mobile/Operators/ConvAddBatchNormReluOp.swift"; sourceTree = SOURCE_ROOT; };
...@@ -280,6 +313,7 @@ ...@@ -280,6 +313,7 @@
FC039B6C20E11C3C0081E9F8 /* paddle-mobile */ = { FC039B6C20E11C3C0081E9F8 /* paddle-mobile */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FCE9D7B6214F869000B520C3 /* Net.swift */,
FC9A19E22148C31300CD9CBF /* MobilenetSSD_AR.swift */, FC9A19E22148C31300CD9CBF /* MobilenetSSD_AR.swift */,
FC33B0EF2147659000714A93 /* MobileNet.swift */, FC33B0EF2147659000714A93 /* MobileNet.swift */,
FC292C862142624800CF622F /* Genet.swift */, FC292C862142624800CF622F /* Genet.swift */,
...@@ -355,6 +389,7 @@ ...@@ -355,6 +389,7 @@
FCBCCC6E2123097100D94F7E /* MulticlassNMSOp.swift */, FCBCCC6E2123097100D94F7E /* MulticlassNMSOp.swift */,
FCDE8A32212A917900F4A8F6 /* ConvTransposeOp.swift */, FCDE8A32212A917900F4A8F6 /* ConvTransposeOp.swift */,
FCEB684B212F093800D2448E /* PreluOp.swift */, FCEB684B212F093800D2448E /* PreluOp.swift */,
FC803BBE214CB65A0094B8E5 /* ConvAddPreluOp.swift */,
); );
path = Operators; path = Operators;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -391,6 +426,7 @@ ...@@ -391,6 +426,7 @@
FCD04E6720F315020007374F /* PoolKernel.swift */, FCD04E6720F315020007374F /* PoolKernel.swift */,
FCD04E6B20F31A280007374F /* SoftmaxKernel.swift */, FCD04E6B20F31A280007374F /* SoftmaxKernel.swift */,
FCD04E6F20F31B720007374F /* ReshapeKernel.swift */, FCD04E6F20F31B720007374F /* ReshapeKernel.swift */,
4AA1EAA1214912CC00D0F791 /* FlattenKernel.swift */,
FCD04E7320F3437E0007374F /* ConvAddKernel.swift */, FCD04E7320F3437E0007374F /* ConvAddKernel.swift */,
FCBCCC5A2122F66F00D94F7E /* ConvBNReluKernel.swift */, FCBCCC5A2122F66F00D94F7E /* ConvBNReluKernel.swift */,
FCBCCC602122FBDF00D94F7E /* PriorBoxKernel.swift */, FCBCCC602122FBDF00D94F7E /* PriorBoxKernel.swift */,
...@@ -402,6 +438,7 @@ ...@@ -402,6 +438,7 @@
4AA1EA87214662BD00D0F791 /* BilinearInterpKernel.swift */, 4AA1EA87214662BD00D0F791 /* BilinearInterpKernel.swift */,
FCBCCC70212309A700D94F7E /* MulticlassNMSKernel.swift */, FCBCCC70212309A700D94F7E /* MulticlassNMSKernel.swift */,
FCDDC6C5212F9FB800E5EF74 /* PreluKernel.swift */, FCDDC6C5212F9FB800E5EF74 /* PreluKernel.swift */,
FC803BC0214CB77A0094B8E5 /* ConvAddPreluKernel.swift */,
); );
path = Kernels; path = Kernels;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -436,27 +473,39 @@ ...@@ -436,27 +473,39 @@
FCEB6837212F00B100D2448E /* metal */ = { FCEB6837212F00B100D2448E /* metal */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FC27990D21341016000B6BAD /* BoxCoder.metal */, 4AF928812135673D005B6C3A /* ConcatKernel.metal */,
4AF928812135673D005B6C3A /* Concat.metal */, 4AA1EA9D2148D6F900D0F791 /* ConcatKernel.inc.metal */,
4AF9288321357BE3005B6C3A /* Elementwise.metal */, 4AF9288321357BE3005B6C3A /* Elementwise.metal */,
FC1B16B220EC9A4F00678B91 /* Kernels.metal */, FC1B16B220EC9A4F00678B91 /* Kernels.metal */,
FC4CB74820F0B954007C0C6D /* ConvKernel.metal */, FC4CB74820F0B954007C0C6D /* ConvKernel.metal */,
4AF928762133F1DB005B6C3A /* BoxCoder.metal */, 4AF928762133F1DB005B6C3A /* BoxCoder.metal */,
4AA1EAA9214F53D800D0F791 /* BoxCoder.inc.metal */,
4AA1EAA5214B5F6800D0F791 /* Shape.metal */,
4AA1EA8F214664CD00D0F791 /* Split.metal */, 4AA1EA8F214664CD00D0F791 /* Split.metal */,
4AA1EAA3214A295C00D0F791 /* Split.inc.metal */,
4AA1EA892146631C00D0F791 /* BilinearInterp.metal */, 4AA1EA892146631C00D0F791 /* BilinearInterp.metal */,
4AA1EAA7214B7AFB00D0F791 /* BilinearInterp.inc.metal */,
4AF9287821341661005B6C3A /* Softmax.metal */, 4AF9287821341661005B6C3A /* Softmax.metal */,
4AA1EAAB214F55C800D0F791 /* Softmax.inc.metal */,
FCEB6849212F00DB00D2448E /* PreluKernel.metal */, FCEB6849212F00DB00D2448E /* PreluKernel.metal */,
FCDDC6C9212FDF6800E5EF74 /* BatchNormKernel.metal */, FCDDC6C9212FDF6800E5EF74 /* BatchNormKernel.metal */,
FCDDC6CB212FDFDB00E5EF74 /* ReluKernel.metal */, FCDDC6CB212FDFDB00E5EF74 /* ReluKernel.metal */,
FCDDC6CE212FE14700E5EF74 /* PriorBoxKernel.metal */, FCDDC6CE212FE14700E5EF74 /* PriorBoxKernel.metal */,
FCA3A1622132A4AC00084FE5 /* ReshapeKernel.metal */, FCA3A1622132A4AC00084FE5 /* ReshapeKernel.metal */,
4AA1EA9F2148DEEE00D0F791 /* ReshapeKernel.inc.metal */,
FCA3A1642132A5EB00084FE5 /* Common.metal */, FCA3A1642132A5EB00084FE5 /* Common.metal */,
FCA67B1621364EF000BD58AA /* ConvTransposeKernel.metal */, FCA67B1621364EF000BD58AA /* ConvTransposeKernel.metal */,
FCA67CD42138272900BD58AA /* ConvAddMetal.metal */, FCA67CD42138272900BD58AA /* ConvAddMetal.metal */,
FCA67CD6213827AC00BD58AA /* ConvAddBNReluKernel.metal */, FCA67CD6213827AC00BD58AA /* ConvAddBNReluKernel.metal */,
FCA67CD82138287B00BD58AA /* ConvBNReluKernel.metal */, FCA67CD82138287B00BD58AA /* ConvBNReluKernel.metal */,
FC0226552138F33800F395E2 /* TransposeKernel.metal */, FC0226552138F33800F395E2 /* TransposeKernel.metal */,
4AA1EAAD214F5FD900D0F791 /* TransposeKernel.inc.metal */,
FC0226572138F38D00F395E2 /* PoolKernel.metal */, FC0226572138F38D00F395E2 /* PoolKernel.metal */,
FC803BC2214CB79C0094B8E5 /* ConvAddPreluKernel.metal */,
FC803BC4214CB8F00094B8E5 /* ConvAddPrelu.inc.metal */,
FC803BC6214CBA820094B8E5 /* Macro.metal */,
FC803BC8214CFC8D0094B8E5 /* FetchKernel.metal */,
FCE9D7B8214FAA4800B520C3 /* NMSFetchResultKernel.metal */,
); );
path = metal; path = metal;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -471,6 +520,7 @@ ...@@ -471,6 +520,7 @@
FC4FD9792140E4980073E130 /* PaddleMobile.h in Headers */, FC4FD9792140E4980073E130 /* PaddleMobile.h in Headers */,
FC292C85214257CB00CF622F /* CPUCompute.h in Headers */, FC292C85214257CB00CF622F /* CPUCompute.h in Headers */,
FC292C5421421B2F00CF622F /* PaddleMobileGPU.h in Headers */, FC292C5421421B2F00CF622F /* PaddleMobileGPU.h in Headers */,
4AA1EA9E2148D6F900D0F791 /* ConcatKernel.inc.metal in Headers */,
FC039B6F20E11C3C0081E9F8 /* paddle_mobile.h in Headers */, FC039B6F20E11C3C0081E9F8 /* paddle_mobile.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
...@@ -566,7 +616,9 @@ ...@@ -566,7 +616,9 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
FC9D038020E22FBB000F735A /* FeedOp.swift in Sources */, FC9D038020E22FBB000F735A /* FeedOp.swift in Sources */,
4AA1EAAA214F53D800D0F791 /* BoxCoder.inc.metal in Sources */,
FC039B9F20E11CB20081E9F8 /* Tensor.swift in Sources */, FC039B9F20E11CB20081E9F8 /* Tensor.swift in Sources */,
FC803BC9214CFC8D0094B8E5 /* FetchKernel.metal in Sources */,
FCA67CD7213827AC00BD58AA /* ConvAddBNReluKernel.metal in Sources */, FCA67CD7213827AC00BD58AA /* ConvAddBNReluKernel.metal in Sources */,
4AF9287921341661005B6C3A /* Softmax.metal in Sources */, 4AF9287921341661005B6C3A /* Softmax.metal in Sources */,
4AA1EA942146661500D0F791 /* ShapeKernel.swift in Sources */, 4AA1EA942146661500D0F791 /* ShapeKernel.swift in Sources */,
...@@ -574,6 +626,9 @@ ...@@ -574,6 +626,9 @@
FC039BAA20E11CBC0081E9F8 /* ElementwiseAddOp.swift in Sources */, FC039BAA20E11CBC0081E9F8 /* ElementwiseAddOp.swift in Sources */,
FCDE8A33212A917900F4A8F6 /* ConvTransposeOp.swift in Sources */, FCDE8A33212A917900F4A8F6 /* ConvTransposeOp.swift in Sources */,
FCBCCC6B2123071700D94F7E /* BoxcoderOp.swift in Sources */, FCBCCC6B2123071700D94F7E /* BoxcoderOp.swift in Sources */,
4AA1EAAE214F5FD900D0F791 /* TransposeKernel.inc.metal in Sources */,
4AA1EAA4214A295C00D0F791 /* Split.inc.metal in Sources */,
FC803BC7214CBA820094B8E5 /* Macro.metal in Sources */,
FC039B9B20E11CA00081E9F8 /* Executor.swift in Sources */, FC039B9B20E11CA00081E9F8 /* Executor.swift in Sources */,
4AF9288421357BE3005B6C3A /* Elementwise.metal in Sources */, 4AF9288421357BE3005B6C3A /* Elementwise.metal in Sources */,
FCD04E7020F31B720007374F /* ReshapeKernel.swift in Sources */, FCD04E7020F31B720007374F /* ReshapeKernel.swift in Sources */,
...@@ -590,10 +645,13 @@ ...@@ -590,10 +645,13 @@
4AA1EA8C2146640900D0F791 /* SplitOp.swift in Sources */, 4AA1EA8C2146640900D0F791 /* SplitOp.swift in Sources */,
FC292C81214255BD00CF622F /* CPUCompute.mm in Sources */, FC292C81214255BD00CF622F /* CPUCompute.mm in Sources */,
FCEBC0F420F1FDD90099DBAF /* ConvAddBatchNormReluOp.swift in Sources */, FCEBC0F420F1FDD90099DBAF /* ConvAddBatchNormReluOp.swift in Sources */,
4AA1EAAC214F55C800D0F791 /* Softmax.inc.metal in Sources */,
FC0E2DC020EE461F009C1FAC /* ElementwiseAddKernel.swift in Sources */, FC0E2DC020EE461F009C1FAC /* ElementwiseAddKernel.swift in Sources */,
4AF928772133F1DB005B6C3A /* BoxCoder.metal in Sources */, 4AF928772133F1DB005B6C3A /* BoxCoder.metal in Sources */,
FC803BBF214CB65A0094B8E5 /* ConvAddPreluOp.swift in Sources */,
FC33B0F02147659000714A93 /* MobileNet.swift in Sources */, FC33B0F02147659000714A93 /* MobileNet.swift in Sources */,
FCEB684C212F093800D2448E /* PreluOp.swift in Sources */, FCEB684C212F093800D2448E /* PreluOp.swift in Sources */,
4AA1EAA8214B7AFB00D0F791 /* BilinearInterp.inc.metal in Sources */,
FCA67CD92138287B00BD58AA /* ConvBNReluKernel.metal in Sources */, FCA67CD92138287B00BD58AA /* ConvBNReluKernel.metal in Sources */,
FC60DB8920E9AAA500FF203F /* MetalExtension.swift in Sources */, FC60DB8920E9AAA500FF203F /* MetalExtension.swift in Sources */,
FCEBC0F620F1FE120099DBAF /* ConvAddBatchNormReluKernel.swift in Sources */, FCEBC0F620F1FE120099DBAF /* ConvAddBatchNormReluKernel.swift in Sources */,
...@@ -610,8 +668,10 @@ ...@@ -610,8 +668,10 @@
FCBCCC592122F42700D94F7E /* ConvBNReluOp.swift in Sources */, FCBCCC592122F42700D94F7E /* ConvBNReluOp.swift in Sources */,
FC039BA920E11CBC0081E9F8 /* ConvOp.swift in Sources */, FC039BA920E11CBC0081E9F8 /* ConvOp.swift in Sources */,
FC9D038420E23B01000F735A /* Texture.swift in Sources */, FC9D038420E23B01000F735A /* Texture.swift in Sources */,
4AA1EAA2214912CD00D0F791 /* FlattenKernel.swift in Sources */,
4AA1EA982146666500D0F791 /* FlattenOp.swift in Sources */, 4AA1EA982146666500D0F791 /* FlattenOp.swift in Sources */,
FCBCCC652122FCD700D94F7E /* TransposeOp.swift in Sources */, FCBCCC652122FCD700D94F7E /* TransposeOp.swift in Sources */,
4AA1EAA6214B5F6800D0F791 /* Shape.metal in Sources */,
FCD04E6E20F31B4B0007374F /* ReshapeOp.swift in Sources */, FCD04E6E20F31B4B0007374F /* ReshapeOp.swift in Sources */,
FC039B9820E11C9A0081E9F8 /* Errors.swift in Sources */, FC039B9820E11C9A0081E9F8 /* Errors.swift in Sources */,
FC039BBF20E11CC20081E9F8 /* Attribute.swift in Sources */, FC039BBF20E11CC20081E9F8 /* Attribute.swift in Sources */,
...@@ -620,11 +680,13 @@ ...@@ -620,11 +680,13 @@
FC039BB920E11CC20081E9F8 /* Scope.swift in Sources */, FC039BB920E11CC20081E9F8 /* Scope.swift in Sources */,
FC292C5621421B4600CF622F /* PaddleMobileGPU.m in Sources */, FC292C5621421B4600CF622F /* PaddleMobileGPU.m in Sources */,
FCD04E6620F314C50007374F /* PoolOp.swift in Sources */, FCD04E6620F314C50007374F /* PoolOp.swift in Sources */,
FCE9D7B9214FAA4800B520C3 /* NMSFetchResultKernel.metal in Sources */,
FC039BAC20E11CBC0081E9F8 /* BatchNormOp.swift in Sources */, FC039BAC20E11CBC0081E9F8 /* BatchNormOp.swift in Sources */,
FCBCCC6F2123097100D94F7E /* MulticlassNMSOp.swift in Sources */, FCBCCC6F2123097100D94F7E /* MulticlassNMSOp.swift in Sources */,
FC039BBC20E11CC20081E9F8 /* VarDesc.swift in Sources */, FC039BBC20E11CC20081E9F8 /* VarDesc.swift in Sources */,
FC292C872142624800CF622F /* Genet.swift in Sources */, FC292C872142624800CF622F /* Genet.swift in Sources */,
4AF928822135673D005B6C3A /* Concat.metal in Sources */, FC803BC5214CB8F00094B8E5 /* ConvAddPrelu.inc.metal in Sources */,
4AF928822135673D005B6C3A /* ConcatKernel.metal in Sources */,
FCBCCC632122FCC000D94F7E /* TransposeKernel.swift in Sources */, FCBCCC632122FCC000D94F7E /* TransposeKernel.swift in Sources */,
FCBCCC71212309A700D94F7E /* MulticlassNMSKernel.swift in Sources */, FCBCCC71212309A700D94F7E /* MulticlassNMSKernel.swift in Sources */,
FCDC0FEB21099A1D00DC9EFB /* Tools.swift in Sources */, FCDC0FEB21099A1D00DC9EFB /* Tools.swift in Sources */,
...@@ -636,7 +698,9 @@ ...@@ -636,7 +698,9 @@
FC82735920E3C04200BE430A /* OpCreator.swift in Sources */, FC82735920E3C04200BE430A /* OpCreator.swift in Sources */,
FCA3A1652132A5EB00084FE5 /* Common.metal in Sources */, FCA3A1652132A5EB00084FE5 /* Common.metal in Sources */,
4AA1EA92214665D700D0F791 /* ShapeOp.swift in Sources */, 4AA1EA92214665D700D0F791 /* ShapeOp.swift in Sources */,
FC803BC1214CB77A0094B8E5 /* ConvAddPreluKernel.swift in Sources */,
FCBCCC5D2122F8A100D94F7E /* DepthwiseConvOp.swift in Sources */, FCBCCC5D2122F8A100D94F7E /* DepthwiseConvOp.swift in Sources */,
FCE9D7B7214F869000B520C3 /* Net.swift in Sources */,
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 */,
...@@ -650,11 +714,13 @@ ...@@ -650,11 +714,13 @@
FCBCCC67212306B000D94F7E /* ConcatOp.swift in Sources */, FCBCCC67212306B000D94F7E /* ConcatOp.swift in Sources */,
FCD04E6C20F31A280007374F /* SoftmaxKernel.swift in Sources */, FCD04E6C20F31A280007374F /* SoftmaxKernel.swift in Sources */,
FCEB684A212F00DB00D2448E /* PreluKernel.metal in Sources */, FCEB684A212F00DB00D2448E /* PreluKernel.metal in Sources */,
4AA1EAA02148DEEE00D0F791 /* ReshapeKernel.inc.metal in Sources */,
FC9A19E32148C31300CD9CBF /* MobilenetSSD_AR.swift in Sources */, FC9A19E32148C31300CD9CBF /* MobilenetSSD_AR.swift in Sources */,
FCDDC6CF212FE14700E5EF74 /* PriorBoxKernel.metal in Sources */, FCDDC6CF212FE14700E5EF74 /* PriorBoxKernel.metal in Sources */,
FC4CB74B20F12C30007C0C6D /* ProgramOptimize.swift in Sources */, FC4CB74B20F12C30007C0C6D /* ProgramOptimize.swift in Sources */,
FC5163F620EF556E00636C28 /* Texture2DTo2DArrayKernel.swift in Sources */, FC5163F620EF556E00636C28 /* Texture2DTo2DArrayKernel.swift in Sources */,
FC039BC020E11CC20081E9F8 /* BlockDesc.swift in Sources */, FC039BC020E11CC20081E9F8 /* BlockDesc.swift in Sources */,
FC803BC3214CB79C0094B8E5 /* ConvAddPreluKernel.metal in Sources */,
4AA1EA90214664CD00D0F791 /* Split.metal in Sources */, 4AA1EA90214664CD00D0F791 /* Split.metal in Sources */,
FCD04E6820F315020007374F /* PoolKernel.swift in Sources */, FCD04E6820F315020007374F /* PoolKernel.swift in Sources */,
FC0226582138F38D00F395E2 /* PoolKernel.metal in Sources */, FC0226582138F38D00F395E2 /* PoolKernel.metal in Sources */,
...@@ -815,7 +881,7 @@ ...@@ -815,7 +881,7 @@
"$(PROJECT_DIR)/paddle-mobile/CPU", "$(PROJECT_DIR)/paddle-mobile/CPU",
); );
MACH_O_TYPE = mh_dylib; MACH_O_TYPE = mh_dylib;
MTL_LANGUAGE_REVISION = UseDeploymentTarget; MTL_LANGUAGE_REVISION = Metal12;
PRODUCT_BUNDLE_IDENTIFIER = "orange.paddle-mobile"; PRODUCT_BUNDLE_IDENTIFIER = "orange.paddle-mobile";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
...@@ -851,7 +917,7 @@ ...@@ -851,7 +917,7 @@
"$(PROJECT_DIR)/paddle-mobile/CPU", "$(PROJECT_DIR)/paddle-mobile/CPU",
); );
MACH_O_TYPE = mh_dylib; MACH_O_TYPE = mh_dylib;
MTL_LANGUAGE_REVISION = UseDeploymentTarget; MTL_LANGUAGE_REVISION = Metal12;
PRODUCT_BUNDLE_IDENTIFIER = "orange.paddle-mobile"; PRODUCT_BUNDLE_IDENTIFIER = "orange.paddle-mobile";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
</AdditionalOptions> </AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Release" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0" launchStyle = "0"
......
...@@ -17,7 +17,17 @@ ...@@ -17,7 +17,17 @@
#import <CoreImage/CoreImage.h> #import <CoreImage/CoreImage.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface PaddleMobile : NSObject @interface PaddleMobileCPUResult: NSObject
@property (assign, nonatomic, readonly) float *output;
@property (assign, nonatomic, readonly) int outputSize;
-(void)releaseOutput;
@end
@interface PaddleMobileCPU : NSObject
/* /*
创建对象 创建对象
...@@ -42,25 +52,8 @@ ...@@ -42,25 +52,8 @@
andModelParamsLen:(size_t)combinedParamsLen andModelParamsLen:(size_t)combinedParamsLen
andCombinedParamsBuf:(const uint8_t *)combinedParamsBuf; andCombinedParamsBuf:(const uint8_t *)combinedParamsBuf;
/*
* 进行预测, means 和 scale 为训练模型时的预处理参数, 如训练时没有做这些预处理则直接使用 predict
*/
- (NSArray *)predict:(CGImageRef)image
dim:(NSArray<NSNumber *> *)dim
means:(NSArray<NSNumber *> *)means
scale:(float)scale;
/*
* 预测输入
* */
- (NSArray *)predictInput:(float *)input
dim:(NSArray<NSNumber *> *)dim
means:(NSArray<NSNumber *> *)means
scale:(float)scale;
/* /*
* 对图像进行预处理 * 对图像进行预处理, 需要外部开辟 output 内存, 外部释放 output 内存
* */ * */
-(void)preprocess:(CGImageRef)image -(void)preprocess:(CGImageRef)image
output:(float *)output output:(float *)output
...@@ -68,6 +61,22 @@ ...@@ -68,6 +61,22 @@
scale:(float)scale scale:(float)scale
dim:(NSArray<NSNumber *> *)dim; dim:(NSArray<NSNumber *> *)dim;
/*
* 预测预处理后的数据, 返回结果使用结束需要调用其 realseOutput 函数进行释放
* */
- (PaddleMobileCPUResult *)predictInput:(float *)input
dim:(NSArray<NSNumber *> *)dim;
/*
进行预测, means 和 scale 为训练模型时的预处理参数, 如训练时没有做这些预处理则直接使用 predict
*/
- (NSArray *)predict:(CGImageRef)image dim:(NSArray<NSNumber *> *)dim means:(NSArray<NSNumber *> *)means scale:(float)scale;
/*
进行预测, 默认 means 为 0, scale 为 1.0
*/
- (NSArray *)predict:(CGImageRef)image dim:(NSArray<NSNumber *> *)dim;
/* /*
清理内存 清理内存
*/ */
......
...@@ -16,6 +16,12 @@ ...@@ -16,6 +16,12 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface CPUResult: NSObject
@property (assign, nonatomic) float *output;
@property (assign, nonatomic) int outputSize;
@end
@interface NMSCompute: NSObject @interface NMSCompute: NSObject
@property (assign, nonatomic) float scoreThredshold; @property (assign, nonatomic) float scoreThredshold;
...@@ -34,6 +40,6 @@ ...@@ -34,6 +40,6 @@
@property (strong, nonatomic) NSArray<NSNumber *> *bboxDim; @property (strong, nonatomic) NSArray<NSNumber *> *bboxDim;
-(NSArray<NSNumber *> *)computeWithScore:(float *)score andBBoxs:(float *)bbox; -(CPUResult *)computeWithScore:(float *)score andBBoxs:(float *)bbox;
@end @end
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#import <algorithm> #import <algorithm>
struct NMSParam { struct NMSParam {
float *score_data; float *score_data;
...@@ -282,9 +284,12 @@ void MultiClassNMSCompute(NMSParam *param) { ...@@ -282,9 +284,12 @@ void MultiClassNMSCompute(NMSParam *param) {
param->output_size = output_size; param->output_size = output_size;
} }
@implementation CPUResult
@end
@implementation NMSCompute @implementation NMSCompute
-(NSArray<NSNumber *> *)computeWithScore:(float *)score andBBoxs:(float *)bbox { -(CPUResult *)computeWithScore:(float *)score andBBoxs:(float *)bbox {
NMSParam param; NMSParam param;
param.box_data = bbox; param.box_data = bbox;
param.score_data = score; param.score_data = score;
...@@ -306,12 +311,10 @@ void MultiClassNMSCompute(NMSParam *param) { ...@@ -306,12 +311,10 @@ void MultiClassNMSCompute(NMSParam *param) {
} }
param.box_dim = box_dim; param.box_dim = box_dim;
MultiClassNMSCompute(&param); MultiClassNMSCompute(&param);
NSMutableArray<NSNumber *> *output = [NSMutableArray arrayWithCapacity:param.output_size]; CPUResult *cr = [[CPUResult alloc] init];
for (int i = 0; i < param.output_size; ++i) { cr.output = param.output;
[output addObject:[NSNumber numberWithFloat:param.output[i]]]; cr.outputSize = param.output_size;
} return cr;
delete param.output;
return output;
} }
@end @end
......
...@@ -71,7 +71,128 @@ extension MTLDevice { ...@@ -71,7 +71,128 @@ extension MTLDevice {
return buffer! return buffer!
} }
func texture2tensor_loop<P>(texture: MTLTexture, cb: ([Int], P)->Void) -> Void {
let bpR = texture.width * 4 * MemoryLayout<P>.size
let bpI = texture.height * bpR
let region = MTLRegion.init(origin: MTLOrigin.init(x: 0, y: 0, z: 0), size: MTLSize.init(width: texture.width, height: texture.height, depth: 1))
for i in 0..<texture.arrayLength {
let pointer: UnsafeMutablePointer<P> = UnsafeMutablePointer<P>.allocate(capacity: bpI)
texture.getBytes(pointer, bytesPerRow: bpR, bytesPerImage: bpI, from: region, mipmapLevel: 0, slice: i)
for tx in 0..<texture.width * texture.height * 4 {
var k = tx
var xyzn: [Int] = [0, 0, 0, 0]
xyzn[1] = k / (texture.width * 4)
k %= (texture.width * 4)
xyzn[3] = k % 4
xyzn[0] = k / 4
xyzn[2] = i
cb(xyzn, pointer[tx])
}
}
}
func texture2tensor_3<P>(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] {
var tdim: [Int] = [1, 1, 1, 1]
for i in 0..<dim.count {
tdim[4 - dim.count + i] = dim[i]
}
let count = dim.reduce(1) { $0 * $1 }
var tensor: [P] = .init(repeating: Float32(0.0) as! P, count: count)
let ndim: [Int] = transpose.map { tdim[$0] }
assert(dim.count == 3)
assert(texture.width == ndim[3])
assert(texture.height == ndim[2])
assert(ndim[0] == 1)
assert(texture.arrayLength == (ndim[1] + 3) / 4)
texture2tensor_loop(texture: texture) { (xyzn: [Int], v: P) in
var tg: [Int] = [0, 0, 0, 0]
tg[1] = xyzn[2] * 4 + xyzn[3]
tg[2] = xyzn[1]
tg[3] = xyzn[0]
var ig: [Int] = [0, 0, 0, 0]
for k in 0..<4 {
ig[transpose[k]] = tg[k]
}
let ix = ig[0] * tdim[1] * tdim[2] * tdim[3] + ig[1] * tdim[2] * tdim[3] + ig[2] * tdim[3] + ig[3]
if ix < count {
tensor[ix] = v
}
}
return tensor
}
func texture2tensor_2<P>(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] {
var tdim: [Int] = [1, 1, 1, 1]
for i in 0..<dim.count {
tdim[4 - dim.count + i] = dim[i]
}
let count = dim.reduce(1) { $0 * $1 }
var tensor: [P] = .init(repeating: Float32(0.0) as! P, count: count)
let ndim: [Int] = transpose.map { tdim[$0] }
assert(dim.count == 2)
let w = (ndim[3] + 3) / 4
assert(texture.width == w)
assert(texture.height == ndim[2])
assert(ndim[0] == 1)
assert(ndim[1] == 1)
assert(texture.arrayLength == 1)
texture2tensor_loop(texture: texture) { (xyzn: [Int], v: P) in
var tg: [Int] = [0, 0, 0, 0]
tg[2] = xyzn[1]
tg[3] = xyzn[0] * 4 + xyzn[3]
var ig: [Int] = [0, 0, 0, 0]
for k in 0..<4 {
ig[transpose[k]] = tg[k]
}
let ix = ig[0] * tdim[1] * tdim[2] * tdim[3] + ig[1] * tdim[2] * tdim[3] + ig[2] * tdim[3] + ig[3]
if ix < count {
tensor[ix] = v
}
}
return tensor
}
func texture2tensor_1<P>(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] {
var tdim: [Int] = [1, 1, 1, 1]
for i in 0..<dim.count {
tdim[4 - dim.count + i] = dim[i]
}
let count = dim.reduce(1) { $0 * $1 }
var tensor: [P] = .init(repeating: Float32(0.0) as! P, count: count)
let ndim: [Int] = transpose.map { tdim[$0] }
assert(dim.count == 1)
let w = (ndim[3] + 3) / 4
assert(texture.width == w)
assert(texture.height == 1)
assert(ndim[0] == 1)
assert(ndim[1] == 1)
assert(ndim[2] == 1)
assert(texture.arrayLength == 1)
texture2tensor_loop(texture: texture) { (xyzn: [Int], v: P) in
var tg: [Int] = [0, 0, 0, 0]
tg[3] = xyzn[0] * 4 + xyzn[3]
var ig: [Int] = [0, 0, 0, 0]
for k in 0..<4 {
ig[transpose[k]] = tg[k]
}
let ix = ig[0] * tdim[1] * tdim[2] * tdim[3] + ig[1] * tdim[2] * tdim[3] + ig[2] * tdim[3] + ig[3]
if ix < count {
tensor[ix] = v
}
}
return tensor
}
func texture2tensor<P>(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] { func texture2tensor<P>(texture: MTLTexture, dim: [Int], transpose: [Int] = [0, 1, 2, 3]) -> [P] {
if dim.count == 3 {
return texture2tensor_3(texture: texture, dim: dim, transpose: transpose)
} else if dim.count == 2 {
return texture2tensor_2(texture: texture, dim: dim, transpose: transpose)
} else if dim.count == 1 {
return texture2tensor_1(texture: texture, dim: dim, transpose: transpose)
}
var tdim: [Int] = [1, 1, 1, 1] var tdim: [Int] = [1, 1, 1, 1]
for i in 0..<dim.count { for i in 0..<dim.count {
tdim[4 - dim.count + i] = dim[i] tdim[4 - dim.count + i] = dim[i]
...@@ -84,30 +205,19 @@ extension MTLDevice { ...@@ -84,30 +205,19 @@ extension MTLDevice {
assert(texture.height == ndim[1]) assert(texture.height == ndim[1])
assert(texture.arrayLength == (ndim[0] * ndim[3] + 3) / 4) assert(texture.arrayLength == (ndim[0] * ndim[3] + 3) / 4)
let bpR = ndim[2] * 4 * MemoryLayout<P>.size texture2tensor_loop(texture: texture) { (xyzn: [Int], v: P) in
let bpI = ndim[1] * bpR var tg: [Int] = [0, 0, 0, 0]
let region = MTLRegion.init(origin: MTLOrigin.init(x: 0, y: 0, z: 0), size: MTLSize.init(width: ndim[2], height: ndim[1], depth: 1)) tg[1] = xyzn[1]
for i in 0..<texture.arrayLength { tg[2] = xyzn[0]
let pointer: UnsafeMutablePointer<P> = UnsafeMutablePointer<P>.allocate(capacity: ndim[1] * ndim[2] * 4 * MemoryLayout<P>.size) tg[0] = (xyzn[2] * 4 + xyzn[3]) / ndim[3]
texture.getBytes(pointer, bytesPerRow: bpR, bytesPerImage: bpI, from: region, mipmapLevel: 0, slice: i) tg[3] = (xyzn[2] * 4 + xyzn[3]) % ndim[3]
var ig: [Int] = [0, 0, 0, 0]
for h in 0..<ndim[1] {
for w in 0..<ndim[2] {
for k in 0..<4 { for k in 0..<4 {
let tx = (h * ndim[2] + w) * 4 + k ig[transpose[k]] = tg[k]
let n = (i * 4 + k) / ndim[3]
let c = (i * 4 + k) % ndim[3]
let jg = [n, h, w, c]
var ig = [0, 0, 0, 0]
for d in 0..<4 {
ig[transpose[d]] = jg[d]
} }
let ix = ig[0] * tdim[1] * tdim[2] * tdim[3] + ig[1] * tdim[2] * tdim[3] + ig[2] * tdim[3] + ig[3] let ix = ig[0] * tdim[1] * tdim[2] * tdim[3] + ig[1] * tdim[2] * tdim[3] + ig[2] * tdim[3] + ig[3]
if ix < count { if ix < count {
tensor[ix] = pointer[tx] tensor[ix] = v
}
}
}
} }
} }
return tensor return tensor
......
...@@ -83,38 +83,38 @@ public class PaddleMobileUnitTest { ...@@ -83,38 +83,38 @@ public class PaddleMobileUnitTest {
} }
public func testConcat() { public func testConcat() {
let buffer = queue.makeCommandBuffer() ?! "buffer is nil" // let buffer = queue.makeCommandBuffer() ?! "buffer is nil"
var it: [[Float32]] = [] // var it: [[Float32]] = []
for _ in 0..<7 { // for _ in 0..<7 {
it.append((0..<12).map { Float32($0) }) // it.append((0..<12).map { Float32($0) })
} // }
let input = it.map { device.tensor2texture(value: $0, dim: [3, 4]) } // let input = it.map { device.tensor2texture(value: $0, dim: [3, 4]) }
let output = device.tensor2texture(value: [Float32](), dim: [3, 28]) // let output = device.tensor2texture(value: [Float32](), dim: [3, 28])
//
let param = ConcatTestParam.init( // let param = ConcatTestParam.init(
input: input, // input: input,
output: output, // output: output,
dims: [[3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4]], // dims: [[3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4]],
axis: 1, // axis: 1,
odim: [3, 28] // odim: [3, 28]
) // )
let concatKernel = ConcatKernel<Float32>.init(device: device, testParam: param) // let concatKernel = ConcatKernel<Float32>.init(device: device, testParam: param)
concatKernel.test(cmdBuffer: buffer, param: param) // concatKernel.test(cmdBuffer: buffer, param: param)
buffer.addCompletedHandler { (buffer) in // buffer.addCompletedHandler { (buffer) in
for i in 0..<it.count { // for i in 0..<it.count {
let _: Float32? = input[i].logDesc() // let _: Float32? = input[i].logDesc()
self.tensorPrint(tensor: it[i], dim: [3, 4]) // self.tensorPrint(tensor: it[i], dim: [3, 4])
} // }
let _: Float32? = output.logDesc() // let _: Float32? = output.logDesc()
let tx: [Float32] = self.device.texture2tensor(texture: output, dim: [3, 28]) // let tx: [Float32] = self.device.texture2tensor(texture: output, dim: [3, 28])
self.tensorPrint(tensor: tx, dim: [3, 28]) // self.tensorPrint(tensor: tx, dim: [3, 28])
} // }
//
buffer.commit() // buffer.commit()
} }
public func testReshape() { public func testReshape() {
let buffer = queue.makeCommandBuffer() ?! "buffer is nil" // let buffer = queue.makeCommandBuffer() ?! "buffer is nil"
// let input: [Float32] = (0..<24).map { Float32($0) } // let input: [Float32] = (0..<24).map { Float32($0) }
// let inTexture = device.tensor2texture(value: input, dim: [2, 3, 4]) // let inTexture = device.tensor2texture(value: input, dim: [2, 3, 4])
// let outTexture = device.tensor2texture(value: [Float32](), dim: [4, 6]) // let outTexture = device.tensor2texture(value: [Float32](), dim: [4, 6])
...@@ -139,32 +139,32 @@ public class PaddleMobileUnitTest { ...@@ -139,32 +139,32 @@ public class PaddleMobileUnitTest {
// self.tensorPrint(tensor: tx, dim: [4, 6]) // self.tensorPrint(tensor: tx, dim: [4, 6])
// } // }
let input: [Float32] = (0..<24).map { Float32($0) } // let input: [Float32] = (0..<24).map { Float32($0) }
let inTexture = device.tensor2texture(value: input, dim: [2, 3, 4]) // let inTexture = device.tensor2texture(value: input, dim: [2, 3, 4])
let outTexture = device.tensor2texture(value: [Float32](), dim: [24]) // let outTexture = device.tensor2texture(value: [Float32](), dim: [24])
let mp = ReshapeMetalParam.init( // let mp = ReshapeMetalParam.init(
idim: (1, 2, 3, 4), // idim: (1, 2, 3, 4),
itrans: (0, 1, 2, 3), // itrans: (0, 1, 2, 3),
odim: (1, 1, 1, 24), // odim: (1, 1, 1, 24),
otrans: (0, 1, 2, 3) // otrans: (0, 1, 2, 3)
) // )
let param = ReshapeTestParam.init( // let param = ReshapeTestParam.init(
inputTexture: inTexture, // inputTexture: inTexture,
outputTexture: outTexture, // outputTexture: outTexture,
param: mp // param: mp
) // )
let reshapeKernel = ReshapeKernel<Float32>.init(device: device, testParam: param) // let reshapeKernel = ReshapeKernel<Float32>.init(device: device, testParam: param)
reshapeKernel.test(commandBuffer: buffer, testParam: param) // reshapeKernel.test(commandBuffer: buffer, testParam: param)
buffer.addCompletedHandler { (buffer) in // buffer.addCompletedHandler { (buffer) in
let _: Float32? = inTexture.logDesc() // let _: Float32? = inTexture.logDesc()
let _: Float32? = outTexture.logDesc() // let _: Float32? = outTexture.logDesc()
self.tensorPrint(tensor: input, dim: [2, 3, 4]) // self.tensorPrint(tensor: input, dim: [2, 3, 4])
let tx: [Float32] = self.device.texture2tensor(texture: outTexture, dim: [24]) // let tx: [Float32] = self.device.texture2tensor(texture: outTexture, dim: [24])
self.tensorPrint(tensor: tx, dim: [24]) // self.tensorPrint(tensor: tx, dim: [24])
} // }
//
//
buffer.commit() // buffer.commit()
} }
public func testTranspose() { public func testTranspose() {
...@@ -195,23 +195,23 @@ public class PaddleMobileUnitTest { ...@@ -195,23 +195,23 @@ public class PaddleMobileUnitTest {
// let tx: [Float32] = self.device.texture2tensor(texture: outputTexture, dim: [3, 3, 2, 4]) // let tx: [Float32] = self.device.texture2tensor(texture: outputTexture, dim: [3, 3, 2, 4])
// self.tensorPrint(tensor: tx, dim: [3, 3, 2, 4]) // self.tensorPrint(tensor: tx, dim: [3, 3, 2, 4])
// } // }
//
let input: [Float32] = (0..<24).map { Float32($0) } // let input: [Float32] = (0..<24).map { Float32($0) }
let inputTexture = device.tensor2texture(value: input, dim: [2, 3, 4]) // let inputTexture = device.tensor2texture(value: input, dim: [2, 3, 4])
let outputTexture = device.tensor2texture(value: [Float](), dim: [3, 4, 2]) // let outputTexture = device.tensor2texture(value: [Float](), dim: [3, 4, 2])
let param = TransposeTestParam.init(inputTexture: inputTexture, outputTexture: outputTexture, iC: 4, oC: 2, axis: [0, 2, 3, 1]) // let param = TransposeTestParam.init(inputTexture: inputTexture, outputTexture: outputTexture, iC: 4, oC: 2, axis: [0, 2, 3, 1])
let transposeKernel = TransposeKernel<Float32>.init(device: device, testParam: param) // let transposeKernel = TransposeKernel<Float32>.init(device: device, testParam: param)
//
transposeKernel.test(commandBuffer: buffer, param: param) // transposeKernel.test(commandBuffer: buffer, param: param)
//
buffer.addCompletedHandler { (buffer) in // buffer.addCompletedHandler { (buffer) in
let _: Float32? = inputTexture.logDesc(header: "input texture", stridable: false) // let _: Float32? = inputTexture.logDesc(header: "input texture", stridable: false)
let _: Float32? = outputTexture.logDesc(header: "output texture", stridable: false) // let _: Float32? = outputTexture.logDesc(header: "output texture", stridable: false)
self.tensorPrint(tensor: input, dim: [2, 3, 4]) // self.tensorPrint(tensor: input, dim: [2, 3, 4])
let tx: [Float32] = self.device.texture2tensor(texture: outputTexture, dim: [3, 4, 2]) // let tx: [Float32] = self.device.texture2tensor(texture: outputTexture, dim: [3, 4, 2])
self.tensorPrint(tensor: tx, dim: [3, 4, 2]) // self.tensorPrint(tensor: tx, dim: [3, 4, 2])
} // }
//
buffer.commit() buffer.commit()
} }
......
...@@ -243,7 +243,7 @@ extension Tensor: Variant { ...@@ -243,7 +243,7 @@ extension Tensor: Variant {
extension Texture: Variant { extension Texture: Variant {
} }
extension ResultHolder: Variant { extension GPUResultHolder: Variant {
} }
extension InputTexture: Variant { extension InputTexture: Variant {
...@@ -252,3 +252,43 @@ extension InputTexture: Variant { ...@@ -252,3 +252,43 @@ extension InputTexture: Variant {
extension MTLTexture where Self: Variant { extension MTLTexture where Self: Variant {
} }
class FetchHolder: Variant {
var resultBuffer: MTLBuffer?
var dim: [Int]
var capacity: Int
init(inCapacity: Int, inDim: [Int]) {
capacity = inCapacity
dim = inDim
}
func initBuffer(device: MTLDevice) {
resultBuffer = device.makeBuffer(length: capacity * 4, options: [])
}
var result: UnsafeMutablePointer<Float32> {
guard let inResultBuffer = resultBuffer else {
fatalError()
}
return inResultBuffer.contents().bindMemory(to: Float32.self, capacity: capacity)
}
}
extension FetchHolder: CustomStringConvertible, CustomDebugStringConvertible {
var description: String {
fatalError()
// return "\(result)"
}
var debugDescription: String {
fatalError()
// return "\(result)"
}
}
...@@ -46,8 +46,9 @@ public class Genet: Net { ...@@ -46,8 +46,9 @@ public class Genet: Net {
} }
} }
override public func resultStr(res: [Float]) -> String { override public func resultStr(res: ResultHolder) -> String {
return " \(Array<Float>(res.suffix(10))) ... " // fatalError()
return " \(res.result![0]) ... "
} }
} }
...@@ -42,9 +42,12 @@ class MobileNet: Net{ ...@@ -42,9 +42,12 @@ class MobileNet: Net{
let labels = PreWords.init(fileName: "synset") let labels = PreWords.init(fileName: "synset")
override public func resultStr(res: [Float]) -> String { override public func resultStr(res: ResultHolder) -> String {
guard let resPointer = res.result else {
fatalError()
}
var s: [String] = [] var s: [String] = []
res.top(r: 5).enumerated().forEach{ (0..<res.capacity).map { resPointer[$0] }.top(r: 5).enumerated().forEach{
s.append(String(format: "%d: %@ (%3.2f%%)", $0 + 1, labels[$1.0], $1.1 * 100)) s.append(String(format: "%d: %@ (%3.2f%%)", $0 + 1, labels[$1.0], $1.1 * 100))
} }
return s.joined(separator: "\n") return s.joined(separator: "\n")
......
...@@ -46,51 +46,52 @@ public class MobileNet_ssd_hand: Net{ ...@@ -46,51 +46,52 @@ public class MobileNet_ssd_hand: Net{
} }
} }
override public func resultStr(res: [Float]) -> String { override public func resultStr(res: ResultHolder) -> String {
return " \(res)" return " \(res)"
} }
override func fetchResult(paddleMobileRes: ResultHolder) -> [Float32] { override func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder {
guard let interRes = paddleMobileRes.intermediateResults else { // guard let interRes = paddleMobileRes.intermediateResults else {
fatalError(" need have inter result ") // 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() // guard let scores = interRes["Scores"], scores.count > 0, let score = scores[0] as? Texture<Float32> else {
// print("bbox: ") // fatalError(" need score ")
// print(bboxArr.strideArray()) // }
//
let nmsCompute = NMSCompute.init() // guard let bboxs = interRes["BBoxes"], bboxs.count > 0, let bbox = bboxs[0] as? Texture<Float32> else {
nmsCompute.scoreThredshold = 0.01 // fatalError()
nmsCompute.nmsTopK = 400 // }
nmsCompute.keepTopK = 200 //
nmsCompute.nmsEta = 1.0 // var scoreFormatArr: [Float32] = score.metalTexture.realNHWC(dim: (n: score.padToFourDim[0], h: score.padToFourDim[1], w: score.padToFourDim[2], c: score.padToFourDim[3]))
nmsCompute.nmsThreshold = 0.45 //// print("score: ")
nmsCompute.background_label = 0; //// print(scoreFormatArr.strideArray())
////
nmsCompute.scoreDim = [NSNumber.init(value: score.tensorDim[0]), NSNumber.init(value: score.tensorDim[1]), NSNumber.init(value: score.tensorDim[2])] // var bboxArr = bbox.metalTexture.float32Array()
//// print("bbox: ")
nmsCompute.bboxDim = [NSNumber.init(value: bbox.tensorDim[0]), NSNumber.init(value: bbox.tensorDim[1]), NSNumber.init(value: bbox.tensorDim[2])] //// print(bboxArr.strideArray())
guard let result = nmsCompute.compute(withScore: &scoreFormatArr, andBBoxs: &bboxArr) else { //
fatalError( " result error " ) // let nmsCompute = NMSCompute.init()
} // nmsCompute.scoreThredshold = 0.01
// nmsCompute.nmsTopK = 400
let output: [Float32] = result.map { $0.floatValue } // nmsCompute.keepTopK = 200
// nmsCompute.nmsEta = 1.0
// nmsCompute.nmsThreshold = 0.45
return output // 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()
} }
......
...@@ -30,50 +30,112 @@ public class MobileNet_ssd_AR: Net{ ...@@ -30,50 +30,112 @@ public class MobileNet_ssd_AR: Net{
class MobilenetssdPreProccess: CusomKernel { class MobilenetssdPreProccess: CusomKernel {
init(device: MTLDevice) { init(device: MTLDevice) {
let s = CusomKernel.Shape.init(inWidth: 160, inHeight: 160, inChannel: 3) let s = CusomKernel.Shape.init(inWidth: 160, inHeight: 160, inChannel: 3)
super.init(device: device, inFunctionName: "mobilent_ar_preprocess_half", outputDim: s, usePaddleMobileLib: false) super.init(device: device, inFunctionName: "mobilent_ar_preprocess", outputDim: s, usePaddleMobileLib: false)
} }
} }
override public func resultStr(res: [Float]) -> String { override public func resultStr(res: ResultHolder) -> String {
return " \(res)" return " \(res.result![0])"
} }
override func fetchResult(paddleMobileRes: ResultHolder) -> [Float32] { override func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder {
guard let interRes = paddleMobileRes.intermediateResults else { guard let interRes = paddleMobileRes.intermediateResults else {
fatalError(" need have inter result ") fatalError(" need have inter result ")
} }
guard let scores = interRes["Scores"], scores.count > 0, let score = scores[0] as? Texture<Float32> else { guard let scores = interRes["Scores"], scores.count > 0, let score = scores[0] as? FetchHolder else {
fatalError(" need score ") fatalError(" need score ")
} }
guard let bboxs = interRes["BBoxes"], bboxs.count > 0, let bbox = bboxs[0] as? Texture<Float32> else { guard let bboxs = interRes["BBoxes"], bboxs.count > 0, let bbox = bboxs[0] as? FetchHolder else {
fatalError() fatalError()
} }
var scoreFormatArr: [Float32] = score.metalTexture.realNHWC(dim: (n: score.padToFourDim[0], h: score.padToFourDim[1], w: score.padToFourDim[2], c: score.padToFourDim[3])) // let startDate = Date.init()
// print("score: ")
// print(scoreFormatArr.strideArray()) // print("scoreFormatArr: ")
// //print((0..<score.capacity).map{ score.result[$0] }.strideArray())
var bboxArr = bbox.metalTexture.float32Array() //
// print("bbox: ") // print("bbox arr: ")
// print(bboxArr.strideArray()) //
// print((0..<bbox.capacity).map{ bbox.result[$0] }.strideArray())
let nmsCompute = NMSCompute.init() let nmsCompute = NMSCompute.init()
nmsCompute.scoreThredshold = 0.01 nmsCompute.scoreThredshold = 0.25
nmsCompute.nmsTopK = 400 nmsCompute.nmsTopK = 100
nmsCompute.keepTopK = 200 nmsCompute.keepTopK = 100
nmsCompute.nmsEta = 1.0 nmsCompute.nmsEta = 1.0
nmsCompute.nmsThreshold = 0.45 nmsCompute.nmsThreshold = 0.449999988
nmsCompute.background_label = 0; 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.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.tensorDim[0]), NSNumber.init(value: bbox.tensorDim[1]), NSNumber.init(value: bbox.tensorDim[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: &scoreFormatArr, andBBoxs: &bboxArr) else { guard let result = nmsCompute.compute(withScore: score.result, andBBoxs: bbox.result) else {
fatalError( " result error " ) 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))
let output: [Float32] = result.map { $0.floatValue } // print(resultHolder.result![0])
return output 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<Float32>
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<Float32>
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<Float32>
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<Float32>
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
}
} }
/* 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
public class ResultHolder: NSObject {
@objc public let result: UnsafeMutablePointer<Float32>?
@objc public let capacity: Int
init(inResult: UnsafeMutablePointer<Float32>?, inCapacity: Int) {
result = inResult
capacity = inCapacity
}
public func releasePointer() {
result?.deinitialize(count: capacity)
result?.deallocate()
}
}
public class Net: NSObject {
var except: Int = 0
var means: [Float] = []
var scale: Float = 0.0
var dim: (n: Int, h: Int, w: Int, c: Int) = (n: 0, h: 0, w: 0, c: 0)
var preprocessKernel: CusomKernel? = nil
var paramPointer: UnsafeMutableRawPointer? = nil
var paramSize: Int = 0
var modelPointer: UnsafeMutableRawPointer? = nil
var modelSize: Int = 0
var modelPath: String = ""
var paramPath: String = ""
var modelDir: String = ""
@objc public init(device: MTLDevice,paramPointer: UnsafeMutableRawPointer, paramSize:Int, modePointer: UnsafeMutableRawPointer, modelSize: Int) {
self.paramPointer = paramPointer
self.paramSize = paramSize
self.modelPointer = modePointer
self.modelSize = modelSize
super.init()
}
public func resultStr(res: ResultHolder) -> String {
fatalError()
}
func fetchResult(paddleMobileRes: GPUResultHolder) -> ResultHolder {
return ResultHolder.init(inResult: paddleMobileRes.resultPointer, inCapacity: paddleMobileRes.capacity)
}
@objc public init(device: MTLDevice) {
super.init()
}
func updateProgram(program: Program) {
}
}
...@@ -64,7 +64,8 @@ class OpCreator<P: PrecisionType> { ...@@ -64,7 +64,8 @@ class OpCreator<P: PrecisionType> {
gBilinearInterpType : BilinearInterpOp<P>.creat, gBilinearInterpType : BilinearInterpOp<P>.creat,
gSplit : SplitOp<P>.creat, gSplit : SplitOp<P>.creat,
gShape : ShapeOp<P>.creat, gShape : ShapeOp<P>.creat,
gFlatten : FlattenOp<P>.creat] gFlatten : FlattenOp<P>.creat,
gConvAddPreluType : ConvAddPreluOp<P>.creat]
private init(){} private init(){}
} }
...@@ -19,6 +19,12 @@ protocol Fusion { ...@@ -19,6 +19,12 @@ protocol Fusion {
static func fusionNode() -> Node static func fusionNode() -> Node
static func change() -> [String : [(from: String, to: String)]] static func change() -> [String : [(from: String, to: String)]]
static func fusionType() -> String static func fusionType() -> String
static func needCheck() -> [(Int, String)]
}
extension Fusion {
static func needCheck() -> [(Int, String)] {
return []
}
} }
protocol Runable { protocol Runable {
...@@ -26,6 +32,7 @@ protocol Runable { ...@@ -26,6 +32,7 @@ protocol Runable {
func runImpl(device: MTLDevice,buffer: MTLCommandBuffer) throws func runImpl(device: MTLDevice,buffer: MTLCommandBuffer) throws
func delogOutput() func delogOutput()
func inputVariant() -> [String : [Variant]] func inputVariant() -> [String : [Variant]]
func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer)
} }
extension Runable where Self: OperatorProtocol{ extension Runable where Self: OperatorProtocol{
...@@ -38,11 +45,16 @@ extension Runable where Self: OperatorProtocol{ ...@@ -38,11 +45,16 @@ extension Runable where Self: OperatorProtocol{
} }
func inputVariant() -> [String : [Variant]] { func inputVariant() -> [String : [Variant]] {
return [:] // return [:]
// fatalError(" op \(type) need implement inputVariant") fatalError(" op \(type) need implement inputVariant")
}
func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) {
fatalError(" need implement ")
} }
func delogOutput() { func delogOutput() {
print(type + ": has no implementation" ) print(type + ": has no implementation" )
} }
} }
...@@ -144,6 +156,7 @@ let gBilinearInterpType = "bilinear_interp" ...@@ -144,6 +156,7 @@ let gBilinearInterpType = "bilinear_interp"
let gSplit = "split" let gSplit = "split"
let gShape = "shape" let gShape = "shape"
let gFlatten = "flatten" let gFlatten = "flatten"
let gConvAddPreluType = "conv_add_prelu"
let opInfos = [gConvType : (inputs: ["Input"], outputs: ["Output"]), let opInfos = [gConvType : (inputs: ["Input"], outputs: ["Output"]),
gBatchNormType : (inputs: ["X"], outputs: ["Y"]), gBatchNormType : (inputs: ["X"], outputs: ["Y"]),
...@@ -169,5 +182,7 @@ let opInfos = [gConvType : (inputs: ["Input"], outputs: ["Out ...@@ -169,5 +182,7 @@ let opInfos = [gConvType : (inputs: ["Input"], outputs: ["Out
gBilinearInterpType : (inputs: ["X"], outputs: ["Out"]), gBilinearInterpType : (inputs: ["X"], outputs: ["Out"]),
gSplit : (inputs: ["X"], outputs: ["Out"]), gSplit : (inputs: ["X"], outputs: ["Out"]),
gShape : (inputs: ["Input"], outputs: ["Out"]), gShape : (inputs: ["Input"], outputs: ["Out"]),
gFlatten : (inputs: ["X"], outputs: ["Out"]) gFlatten : (inputs: ["X"], outputs: ["Out"]),
gConvAddPreluType : (inputs: ["Input"], outputs: ["Out"])
] ]
...@@ -19,11 +19,14 @@ class BatchNormParam<P: PrecisionType>: OpParam { ...@@ -19,11 +19,14 @@ class BatchNormParam<P: PrecisionType>: OpParam {
required init(opDesc: OpDesc, inScope: Scope) throws { required init(opDesc: OpDesc, inScope: Scope) throws {
do { 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] {
fatalError("batch norm only accepts NHWC")
}
output = try BatchNormParam.outputY(outputs: opDesc.outputs, from: inScope) output = try BatchNormParam.outputY(outputs: opDesc.outputs, from: inScope)
inputBias = try BatchNormParam.inputBiase(inputs: opDesc.paraInputs, from: inScope) bias = try BatchNormParam.getFirstTensor(key: "Bias", map: opDesc.paraInputs, from: inScope)
inputMean = try BatchNormParam.inputMean(inputs: opDesc.paraInputs, from: inScope) mean = try BatchNormParam.getFirstTensor(key: "Mean", map: opDesc.paraInputs, from: inScope)
inputScale = try BatchNormParam.inputScale(inputs: opDesc.paraInputs, from: inScope) scale = try BatchNormParam.getFirstTensor(key: "Scale", map: opDesc.paraInputs, from: inScope)
inputVariance = try BatchNormParam.inputVariance(inputs: opDesc.paraInputs, from: inScope) variance = try BatchNormParam.getFirstTensor(key: "Variance", map: opDesc.paraInputs, from: inScope)
epsilon = try BatchNormParam.getAttr(key: "epsilon", attrs: opDesc.attrs) epsilon = try BatchNormParam.getAttr(key: "epsilon", attrs: opDesc.attrs)
momentum = try BatchNormParam.getAttr(key: "momentum", attrs: opDesc.attrs) momentum = try BatchNormParam.getAttr(key: "momentum", attrs: opDesc.attrs)
} catch let error { } catch let error {
...@@ -32,10 +35,10 @@ class BatchNormParam<P: PrecisionType>: OpParam { ...@@ -32,10 +35,10 @@ class BatchNormParam<P: PrecisionType>: OpParam {
} }
let input: Texture<P> let input: Texture<P>
var output: Texture<P> var output: Texture<P>
let inputBias: Tensor<ParamPrecisionType> let bias: Tensor<P>
let inputMean: Tensor<ParamPrecisionType> let mean: Tensor<P>
let inputScale: Tensor<ParamPrecisionType> let scale: Tensor<P>
let inputVariance: Tensor<ParamPrecisionType> let variance: Tensor<P>
let epsilon: Float let epsilon: Float
let momentum: Float let momentum: Float
} }
...@@ -53,9 +56,11 @@ class BatchNormOp<P: PrecisionType>: Operator<BatchNormKernel<P>, BatchNormParam ...@@ -53,9 +56,11 @@ class BatchNormOp<P: PrecisionType>: Operator<BatchNormKernel<P>, BatchNormParam
throw error throw error
} }
} }
}
func delogOutput() {
print(" \(type) output: ")
let device = para.output.metalTexture!.device
let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
print(outputArray.strideArray())
}
}
...@@ -19,15 +19,15 @@ class BilinearInterpParam<P: PrecisionType>: OpParam { ...@@ -19,15 +19,15 @@ class BilinearInterpParam<P: PrecisionType>: OpParam {
required init(opDesc: OpDesc, inScope: Scope) throws { required init(opDesc: OpDesc, inScope: Scope) throws {
do { do {
input = try BilinearInterpParam.inputX(inputs: opDesc.inputs, from: inScope) input = try BilinearInterpParam.inputX(inputs: opDesc.inputs, from: inScope)
// if (input.transpose != [0, 2, 3, 1]) || (input.tensorDim.cout() != 4) {
// fatalError()
// }
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 { } catch let error {
throw error throw error
} }
if (input.transpose != [0, 2, 3, 1]) || (input.tensorDim.cout() != 4) {
fatalError()
}
} }
let input: Texture<P> let input: Texture<P>
var output: Texture<P> var output: Texture<P>
...@@ -53,6 +53,10 @@ class BilinearInterpOp<P: PrecisionType>: Operator<BilinearInterpKernel<P>, Bili ...@@ -53,6 +53,10 @@ class BilinearInterpOp<P: PrecisionType>: Operator<BilinearInterpKernel<P>, Bili
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
let device = para.output.metalTexture!.device
let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
// print(outputArray)
print(outputArray.strideArray())
} }
} }
......
...@@ -27,6 +27,10 @@ class BoxcoderParam<P: PrecisionType>: OpParam { ...@@ -27,6 +27,10 @@ class BoxcoderParam<P: PrecisionType>: OpParam {
} catch let error { } catch let error {
throw error throw error
} }
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(priorBox.transpose == [0, 1, 2, 3])
assert(priorBoxVar.transpose == [0, 1, 2, 3]) assert(priorBoxVar.transpose == [0, 1, 2, 3])
assert(targetBox.transpose == [0, 1, 2, 3]) assert(targetBox.transpose == [0, 1, 2, 3])
...@@ -59,30 +63,19 @@ class BoxcoderOp<P: PrecisionType>: Operator<BoxcoderKernel<P>, BoxcoderParam<P> ...@@ -59,30 +63,19 @@ class BoxcoderOp<P: PrecisionType>: Operator<BoxcoderKernel<P>, BoxcoderParam<P>
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
// let priorBoxpadToFourDim = para.priorBox.padToFourDim let device = para.output.metalTexture!.device
// let priorBoxArray: [Float32] = para.priorBox.metalTexture.realNHWC(dim: (n: priorBoxpadToFourDim[0], h: priorBoxpadToFourDim[1], w: priorBoxpadToFourDim[2], c: priorBoxpadToFourDim[3])) let pbv : [Float32] = device.texture2tensor(texture: para.priorBoxVar.metalTexture!, dim: para.priorBoxVar.tensorDim.dims, transpose: para.priorBoxVar.transpose)
// print(" prior box ") let pb : [Float32] = device.texture2tensor(texture: para.priorBox.metalTexture!, dim: para.priorBox.tensorDim.dims, transpose: para.priorBox.transpose)
// print(priorBoxArray.strideArray()) 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)
// let priorBoxVarpadToFourDim = para.priorBoxVar.padToFourDim print(" prior box var ")
// let priorBoxVarArray: [Float32] = para.priorBoxVar.metalTexture.realNHWC(dim: (n: priorBoxVarpadToFourDim[0], h: priorBoxVarpadToFourDim[1], w: priorBoxVarpadToFourDim[2], c: priorBoxVarpadToFourDim[3])) print(pbv.strideArray())
// print(" prior box var ")
// print(priorBoxVarArray.strideArray())
//
// let targetBoxpadToFourDim = para.targetBox.padToFourDim
// let targetBoxArray: [Float32] = para.targetBox.metalTexture.realNHWC(dim: (n: targetBoxpadToFourDim[0], h: targetBoxpadToFourDim[1], w: targetBoxpadToFourDim[2], c: targetBoxpadToFourDim[3]))
// print(" target box ")
// print(targetBoxArray.strideArray())
let targetBoxpadToFourDim = para.targetBox.padToFourDim
let targetBoxArray = para.targetBox.metalTexture.realNHWC(dim: (n: targetBoxpadToFourDim[0], h: targetBoxpadToFourDim[1], w: targetBoxpadToFourDim[2], c: targetBoxpadToFourDim[3]))
print(" target box ") print(" target box ")
print(targetBoxArray.strideArray()) print(tb.strideArray())
print(" prior box ")
let padToFourDim = para.output.padToFourDim print(pb.strideArray())
let outputArray: [Float32] = para.output.metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3]))
print(" output ") print(" output ")
print(outputArray.strideArray()) print(out.strideArray())
} }
} }
......
...@@ -65,15 +65,10 @@ class ConcatOp<P: PrecisionType>: Operator<ConcatKernel<P>, ConcatParam<P>>, Run ...@@ -65,15 +65,10 @@ class ConcatOp<P: PrecisionType>: Operator<ConcatKernel<P>, ConcatParam<P>>, Run
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
let padToFourDim = para.output.padToFourDim
if para.output.transpose == [0, 1, 2, 3] { let device = para.output.metalTexture!.device
let outputArray: [Float32] = para.output.metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3])) let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
print(outputArray.strideArray()) print(outputArray.strideArray())
} else if para.output.transpose == [0, 2, 3, 1] {
print(para.output.metalTexture.toTensor(dim: (n: padToFourDim[0], c: padToFourDim[1], h: padToFourDim[2], w: padToFourDim[3])).strideArray())
} else {
fatalError(" not implemet")
}
} }
} }
......
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
import Foundation
class ConvAddPreluParam<P: PrecisionType>: OpParam {
typealias ParamPrecisionType = P
required init(opDesc: OpDesc, inScope: Scope) throws {
do {
filter = try ConvAddPreluParam.inputFilter(paraInputs: opDesc.paraInputs, from: inScope)
input = try ConvAddPreluParam.input(inputs: opDesc.inputs, from: inScope)
output = try ConvAddPreluParam.outputOut(outputs: opDesc.outputs, from: inScope)
stride = try ConvAddPreluParam.getAttr(key: "strides", attrs: opDesc.attrs)
paddings = try ConvAddPreluParam.getAttr(key: "paddings", attrs: opDesc.attrs)
dilations = try ConvAddPreluParam.getAttr(key: "dilations", attrs: opDesc.attrs)
groups = try ConvAddPreluParam.getAttr(key: "groups", attrs: opDesc.attrs)
alpha = try ConvAddPreluParam.paramInputAlpha(inputs: opDesc.paraInputs, from: inScope)
mode = try ConvAddPreluParam.getAttr(key: "mode", attrs: opDesc.attrs)
y = try ConvAddPreluParam.inputY(inputs: opDesc.paraInputs, from: inScope)
} catch let error {
throw error
}
}
let input: Texture<P>
let y: Tensor<ParamPrecisionType>
let filter: Tensor<ParamPrecisionType>
let mode: String
let alpha: Tensor<P>
var output: Texture<P>
let stride: [Int32]
let paddings: [Int32]
let dilations: [Int32]
let groups: Int
}
class ConvAddPreluOp<P: PrecisionType>: Operator<ConvAddPreluKernel<P>, ConvAddPreluParam<P>>, Runable, Creator, InferShaperable, Fusion{
typealias OpType = ConvAddPreluOp<P>
static func fusionNode() -> Node {
let beginNode = Node.init(inType: gConvType)
_ = beginNode
--> Node.init(inType: gElementwiseAddType) --> Node.init(inType: gPreluType)
return beginNode
}
static func change() -> [String : [(from: String, to: String)]] {
return [:]
}
static func fusionType() -> String {
return gConvAddPreluType
}
func inferShape() {
let inDims = para.input.dim
let filterDim = para.filter.dim
let strides = para.stride
let paddings = para.paddings
let dilations = para.dilations
var outDim = [inDims[0]]
for i in 0..<strides.count {
let dilation: Int = Int(dilations[i])
let filterSize: Int = filterDim[i + 1]
let inputSize: Int = inDims[i + 1]
let padding: Int = Int(paddings[i])
let stride: Int = Int(strides[i])
let dKernel = dilation * (filterSize - 1) + 1
let outputSize = (inputSize + 2 * padding - dKernel) / stride + 1
outDim.append(outputSize)
}
outDim.append(filterDim[0])
para.output.dim = Dim.init(inDim: outDim)
}
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do {
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
}
func delogOutput() {
print(" \(type) output: ")
print(para.output.metalTexture.toTensor(dim: (n: para.output.tensorDim[0], c: para.output.tensorDim[1], h: para.output.tensorDim[2], w: para.output.tensorDim[3])).strideArray())
}
}
...@@ -15,14 +15,15 @@ ...@@ -15,14 +15,15 @@
import Foundation import Foundation
class FetchParam<P: PrecisionType>: OpParam{ class FetchParam<P: PrecisionType>: OpParam{
var output: Texture<P> var output: FetchHolder
let input: Texture<P> let input: Texture<P>
let scope: Scope let scope: Scope
required init(opDesc: OpDesc, inScope: Scope) throws { required init(opDesc: OpDesc, inScope: Scope) throws {
scope = inScope scope = inScope
do { do {
input = try FetchParam.inputX(inputs: opDesc.inputs, from: inScope) input = try FetchParam.inputX(inputs: opDesc.inputs, from: inScope)
output = input output = FetchHolder.init(inCapacity: input.numel(), inDim: input.tensorDim.dims)
scope.setOutput(output: output)
} catch let error { } catch let error {
throw error throw error
} }
...@@ -34,14 +35,40 @@ class FetchParam<P: PrecisionType>: OpParam{ ...@@ -34,14 +35,40 @@ class FetchParam<P: PrecisionType>: OpParam{
class FetchKernel<P: PrecisionType>: Kernel, Computable { class FetchKernel<P: PrecisionType>: Kernel, Computable {
func compute(commandBuffer: MTLCommandBuffer, param: FetchParam<P>) throws { func compute(commandBuffer: MTLCommandBuffer, param: FetchParam<P>) throws {
guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
throw PaddleMobileError.predictError(message: " encode is nil")
}
encoder.setTexture(param.input.metalTexture, index: 0)
encoder.setBuffer(param.output.resultBuffer!, offset: 0, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: param.input.metalTexture)
encoder.endEncoding()
} }
required init(device: MTLDevice, param: FetchParam<P>) { required init(device: MTLDevice, param: FetchParam<P>) {
super.init(device: device, inFunctionName: "place_holder") param.output.initBuffer(device: device)
if computePrecision == .Float16 {
if param.input.transpose == [0, 2, 3, 1] {
super.init(device: device, inFunctionName: "fetch_half")
} else {
// fatalError(" not support ")
super.init(device: device, inFunctionName: "fetch_placeholder_half")
print(" not support ")
}
} else if computePrecision == .Float32 {
if param.input.transpose == [0, 2, 3, 1] {
super.init(device: device, inFunctionName: "fetch")
} else {
print(" not support ")
super.init(device: device, inFunctionName: "fetch_placeholder")
// fatalError(" not support ")
}
} else {
fatalError(" not support ")
}
} }
} }
class FetchOp<P: PrecisionType>: Operator< FetchKernel<P>, FetchParam<P>>, Runable, Creator, InferShaperable{ class FetchOp<P: PrecisionType>: Operator< FetchKernel<P>, FetchParam<P>>, Runable, Creator, InferShaperable {
typealias OpType = FetchOp<P> typealias OpType = FetchOp<P>
...@@ -50,7 +77,11 @@ class FetchOp<P: PrecisionType>: Operator< FetchKernel<P>, FetchParam<P>>, Runab ...@@ -50,7 +77,11 @@ class FetchOp<P: PrecisionType>: Operator< FetchKernel<P>, FetchParam<P>>, Runab
} }
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
scope.setOutput(output: para.output) do {
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
}
} }
} }
...@@ -14,7 +14,24 @@ ...@@ -14,7 +14,24 @@
import Foundation import Foundation
class FlattenOp<P: PrecisionType>: Operator<ReshapeKernel<P>, ReshapeParam<P>>, Runable, Creator, InferShaperable{ class FlattenParam<P: PrecisionType>: OpParam {
typealias ParamPrecisionType = P
required init(opDesc: OpDesc, inScope: Scope) throws {
do {
input = try FlattenParam.inputX(inputs: opDesc.inputs, from: inScope)
output = try FlattenParam.outputOut(outputs: opDesc.outputs, from: inScope)
axis = try FlattenParam.getAttr(key: "axis", attrs: opDesc.attrs)
} catch let error {
throw error
}
}
let input: Texture<P>
var output: Texture<P>
let axis: Int
}
class FlattenOp<P: PrecisionType>: Operator<FlattenKernel<P>, FlattenParam<P>>, Runable, Creator, InferShaperable{
typealias OpType = FlattenOp<P> typealias OpType = FlattenOp<P>
...@@ -32,6 +49,9 @@ class FlattenOp<P: PrecisionType>: Operator<ReshapeKernel<P>, ReshapeParam<P>>, ...@@ -32,6 +49,9 @@ class FlattenOp<P: PrecisionType>: Operator<ReshapeKernel<P>, ReshapeParam<P>>,
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
let device = para.output.metalTexture!.device
let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
print(outputArray.strideArray())
} }
} }
......
...@@ -15,20 +15,21 @@ ...@@ -15,20 +15,21 @@
import Foundation import Foundation
class BatchNormKernel<P: PrecisionType>: Kernel, Computable { class BatchNormKernel<P: PrecisionType>: Kernel, Computable {
// var newScale: MTLBuffer
// var newBias: MTLBuffer
//
required init(device: MTLDevice, param: BatchNormParam<P>) { required init(device: MTLDevice, param: BatchNormParam<P>) {
// guard let newScale = device.makeBuffer(length: param.inputScale.buffer.length) else { let count = param.variance.dim.numel()
// fatalError() let varianceP = param.variance.data.pointer
// } let meanP = param.mean.data.pointer
// let scaleP = param.scale.data.pointer
// guard let newBias = device.makeBuffer(length: param.inputBias.buffer.length) else { let biasP = param.bias.data.pointer
// fatalError() for i in 0..<count {
// } let invStd = P(1 / (Float32(varianceP[i]) + param.epsilon).squareRoot())
// self.newScale = newScale biasP[i] = biasP[i] - meanP[i] * invStd * scaleP[i]
// self.newBias = newBias scaleP[i] = invStd * scaleP[i]
// }
param.bias.initBuffer(device: device, precision: computePrecision)
param.scale.initBuffer(device: device, precision: computePrecision)
param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: computePrecision)
if computePrecision == .Float32 { if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "batchnorm") super.init(device: device, inFunctionName: "batchnorm")
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
...@@ -36,37 +37,16 @@ class BatchNormKernel<P: PrecisionType>: Kernel, Computable { ...@@ -36,37 +37,16 @@ class BatchNormKernel<P: PrecisionType>: Kernel, Computable {
} else { } else {
fatalError() fatalError()
} }
//
// let varianceBuffer : MTLBuffer = param.inputVariance.buffer
//
// var invStd: [Float32] = Array(repeating: 0, count: varianceBuffer.length)
// let varianceContents = varianceBuffer.contents().assumingMemoryBound(to: P.self)
// for i in 0..<(varianceBuffer.length / MemoryLayout<P>.stride) {
// invStd[i] = 1 / (Float32(varianceContents[i]) + param.epsilon).squareRoot()
// }
//
// let newScaleContents = newScale.contents().assumingMemoryBound(to: P.self)
// let newBiasContents = newBias.contents().assumingMemoryBound(to: P.self)
// let scale : MTLBuffer = param.inputScale.buffer
// let scaleContents = scale.contents().assumingMemoryBound(to: P.self)
// let bias : MTLBuffer = param.inputBias.buffer
// let biasContents = bias.contents().assumingMemoryBound(to: P.self)
// let meanContents = param.inputMean.buffer.contents().assumingMemoryBound(to: P.self)
//
// for i in 0..<(newScale.length / MemoryLayout<P>.stride) {
// newScaleContents[i] = P(invStd[i] * Float32(scaleContents[i]))
// newBiasContents[i] = P(Float32(biasContents[i]) - Float32(meanContents[i]) * invStd[i] * Float32(scaleContents[i]))
// }
} }
func compute(commandBuffer: MTLCommandBuffer, param: BatchNormParam<P>) throws { func compute(commandBuffer: MTLCommandBuffer, param: BatchNormParam<P>) throws {
guard let encoder = commandBuffer.makeComputeCommandEncoder() else { guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
throw PaddleMobileError.predictError(message: " encoder is nil") throw PaddleMobileError.predictError(message: " encoder is nil")
} }
// encoder.setTexture(param.input.metalTexture, index: 0) encoder.setTexture(param.input.metalTexture, index: 0)
// encoder.setTexture(param.output.metalTexture, index: 1) encoder.setTexture(param.output.metalTexture, index: 1)
// encoder.setBuffer(newScale, offset: 0, index: 0) encoder.setBuffer(param.scale.buffer, offset: 0, index: 0)
// encoder.setBuffer(newBias, offset: 0, index: 1) encoder.setBuffer(param.bias.buffer, offset: 0, index: 1)
encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture)
encoder.endEncoding() encoder.endEncoding()
} }
......
...@@ -27,10 +27,16 @@ class BilinearInterpKernel<P: PrecisionType>: Kernel, Computable{ ...@@ -27,10 +27,16 @@ class BilinearInterpKernel<P: PrecisionType>: Kernel, Computable{
encoder.setTexture(param.input.metalTexture, index: 0) encoder.setTexture(param.input.metalTexture, index: 0)
encoder.setTexture(param.output.metalTexture, index: 1) encoder.setTexture(param.output.metalTexture, index: 1)
let ratio_h: Float32 = Float32(param.input.tensorDim.dims[2]) / Float32(param.output.tensorDim.dims[2]) var ratio_h: Float32 = 0
let ratio_w: Float32 = Float32(param.input.tensorDim.dims[3]) / Float32(param.output.tensorDim.dims[3]) var ratio_w: Float32 = 0
if param.output.tensorDim.dims[2] > 1 {
ratio_h = Float32(param.input.tensorDim.dims[2]-1) / Float32(param.output.tensorDim.dims[2]-1)
}
if param.output.tensorDim.dims[3] > 1 {
ratio_w = Float32(param.input.tensorDim.dims[3]-1) / Float32(param.output.tensorDim.dims[3]-1)
}
var p = BilinearInterpMetalParam.init(ratio_h: ratio_h, ratio_w: ratio_w) var p = BilinearInterpMetalParam.init(ratio_h: ratio_h, ratio_w: ratio_w)
encoder.setBytes(&p, length: MemoryLayout<ConcatMetalParam>.size, index: 0) encoder.setBytes(&p, length: MemoryLayout<BilinearInterpMetalParam>.size, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture) encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture)
encoder.endEncoding() encoder.endEncoding()
} }
...@@ -38,7 +44,7 @@ class BilinearInterpKernel<P: PrecisionType>: Kernel, Computable{ ...@@ -38,7 +44,7 @@ class BilinearInterpKernel<P: PrecisionType>: Kernel, Computable{
required init(device: MTLDevice, param: BilinearInterpParam<P>) { required init(device: MTLDevice, param: BilinearInterpParam<P>) {
param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: computePrecision) param.output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: computePrecision)
if computePrecision == .Float32 { if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "bilinear_interp") super.init(device: device, inFunctionName: "bilinear_interp_float")
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "bilinear_interp_half") super.init(device: device, inFunctionName: "bilinear_interp_half")
} else { } else {
......
...@@ -33,9 +33,9 @@ class BoxcoderKernel<P: PrecisionType>: Kernel, Computable{ ...@@ -33,9 +33,9 @@ class BoxcoderKernel<P: PrecisionType>: Kernel, Computable{
} }
required init(device: MTLDevice, param: BoxcoderParam<P>) { required init(device: MTLDevice, param: BoxcoderParam<P>) {
param.output.initTexture(device: device, computePrecision: computePrecision) param.output.initTexture(device: device, inTranspose: [0, 3, 1, 2], computePrecision: computePrecision)
if computePrecision == .Float32 { if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "boxcoder") super.init(device: device, inFunctionName: "boxcoder_float")
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "boxcoder_half") super.init(device: device, inFunctionName: "boxcoder_half")
} else { } else {
......
...@@ -31,101 +31,111 @@ struct ConcatMetalParam { ...@@ -31,101 +31,111 @@ struct ConcatMetalParam {
} }
class ConcatKernel<P: PrecisionType>: Kernel, Computable{ class ConcatKernel<P: PrecisionType>: Kernel, Computable{
var v = "normal"
var pm = ConcatMetalParam.init()
func compute(commandBuffer: MTLCommandBuffer, param: ConcatParam<P>) throws {
func encodeTest(_ cmdBuffer: MTLCommandBuffer, _ param: ConcatTestParam, _ istart: Int, _ iend: Int) { guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
let encoder = cmdBuffer.makeComputeCommandEncoder()! throw PaddleMobileError.predictError(message: " encode is nil")
var p = ConcatMetalParam.init() }
var odim: [Int32] = [1, 1, 1, 1] let num = param.input.count
for i in 0..<param.odim.count { for i in 0..<num {
odim[4-param.odim.count+i] = Int32(param.odim[i]) encoder.setTexture(param.input[i].metalTexture, index: i)
} }
p.odim = (odim[0], odim[1], odim[2], odim[3]) encoder.setTexture(param.output.metalTexture, index: num)
p.axis = Int32(4 - param.odim.count + param.axis) if v == "normal" {
for i in 0..<istart { encoder.setTexture(param.output.metalTexture, index: num + 1)
p.offset += Int32(param.dims[i][param.axis]) }
} encoder.setBytes(&pm, length: MemoryLayout<ConcatMetalParam>.size, index: 0)
var vdim: [Int32] = [] encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture)
for i in 0..<(iend - istart) {
encoder.setTexture(param.input[i+istart], index: i)
vdim.append(Int32(param.dims[i+istart][Int(param.axis)]))
}
for i in (iend-istart)..<6 {
encoder.setTexture(param.input[0], index: i)
vdim.append(0)
}
p.vdim = (vdim[0], vdim[1], vdim[2], vdim[3], vdim[4], vdim[5])
encoder.setTexture(param.output, index: 6)
encoder.setTexture(param.output, index: 7)
encoder.setBytes(&p, length: MemoryLayout<ConcatMetalParam>.size, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: param.output)
encoder.endEncoding() encoder.endEncoding()
} }
func encode(_ cmdBuffer: MTLCommandBuffer, _ param: ConcatParam<P>, _ istart: Int, _ iend: Int) throws { required init(device: MTLDevice, param: ConcatParam<P>) {
guard let encoder = cmdBuffer.makeComputeCommandEncoder() else { param.output.initTexture(device: device, inTranspose: param.transpose, computePrecision: computePrecision)
throw PaddleMobileError.predictError(message: " encode is nil") let orank = param.output.tensorDim.cout()
} let num = param.input.count
var p = ConcatMetalParam.init() assert(num <= 6)
let odim = (0..<4).map { Int32(param.output.dim[$0]) } var axis = 4 - param.output.tensorDim.cout() + param.axis
p.odim = (odim[0], odim[1], odim[2], odim[3])
p.axis = Int32(4 - param.output.tensorDim.cout() + param.axis)
for i in 0..<4 { for i in 0..<4 {
if Int32(param.transpose[i]) == p.axis { if param.transpose[i] == axis {
p.axis = Int32(i) axis = i
break break
} }
} }
for i in 0..<istart { pm.axis = Int32(axis)
p.offset += Int32(param.input[i+istart].dim[Int(p.axis)]) pm.odim = (Int32(param.output.dim[0]), Int32(param.output.dim[1]), Int32(param.output.dim[2]), Int32(param.output.dim[3]))
pm.trans = (Int32(param.output.transpose[0]), Int32(param.output.transpose[1]), Int32(param.output.transpose[2]), Int32(param.output.transpose[3]))
var vdim: [Int] = [0, 0, 0, 0, 0, 0]
for i in 0..<num {
vdim[i] = param.input[i].dim[axis]
} }
var vdim: [Int32] = [] if orank == 4 {
for i in 0..<(iend - istart) { if axis == 1 {
encoder.setTexture(param.input[i+istart].metalTexture, index: i) v = "y"
vdim.append(Int32(param.input[i+istart].dim[Int(p.axis)])) } else if axis == 2 {
v = "x"
} else {
if (param.output.dim[0] == 1) && axis == 3 {
var vz = true
for i in 0..<num {
if vdim[i] % 4 != 0 {
vz = false
break
} }
for i in (iend-istart)..<6 {
encoder.setTexture(param.input[0].metalTexture, index: i)
vdim.append(0)
} }
p.trans = (Int32(param.transpose[0]), Int32(param.transpose[1]), Int32(param.transpose[2]), Int32(param.transpose[3])) if vz {
v = "z"
p.vdim = (vdim[0], vdim[1], vdim[2], vdim[3], vdim[4], vdim[5]) for i in 0..<num {
encoder.setTexture(param.output.metalTexture, index: 6) vdim[i] = vdim[i] / 4
encoder.setTexture(param.output.metalTexture, index: 7)
encoder.setBytes(&p, length: MemoryLayout<ConcatMetalParam>.size, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture)
encoder.endEncoding()
} }
func compute(commandBuffer: MTLCommandBuffer, param: ConcatParam<P>) throws {
let group = param.input.count / 6
let remain = param.input.count % 6
for i in 0..<group {
try self.encode(commandBuffer, param, 6 * i, 6 * (i + 1))
} }
if remain > 0 {
try self.encode(commandBuffer, param, 6 * group, param.input.count)
} }
} }
} else if orank == 3 {
func test(cmdBuffer: MTLCommandBuffer, param: ConcatTestParam) { if axis == 2 {
let group = param.input.count / 6 v = "y"
let remain = param.input.count % 6 } else if axis == 3 {
for i in 0..<group { v = "x"
self.encodeTest(cmdBuffer, param, 6 * i, 6 * (i + 1)) } else if axis == 1 {
var vz = true
for i in 0..<num {
if vdim[i] % 4 != 0 {
vz = false
break
} }
if remain > 0 {
self.encodeTest(cmdBuffer, param, 6 * group, param.input.count)
} }
if vz {
v = "z"
for i in 0..<num {
vdim[i] = vdim[i] / 4
} }
}
required init(device: MTLDevice, param: ConcatParam<P>) { }
param.output.initTexture(device: device, inTranspose: param.transpose, computePrecision: computePrecision) } else {
if axis == 2 {
v = "y"
} else if axis == 3 {
var vx = true
for i in 0..<num {
if vdim[i] % 4 != 0 {
vx = false
break
}
}
if vx {
v = "x"
for i in 0..<num {
vdim[i] = vdim[i] / 4
}
}
}
}
pm.vdim = (Int32(vdim[0]), Int32(vdim[1]), Int32(vdim[2]), Int32(vdim[3]), Int32(vdim[4]), Int32(vdim[5]))
if computePrecision == .Float32 { if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "concat") super.init(device: device, inFunctionName: "concat_\(orank)_\(num)_\(v)_float")
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "concat_half") super.init(device: device, inFunctionName: "concat_\(orank)_\(num)_\(v)_half")
} else { } else {
fatalError() fatalError()
} }
......
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
import Foundation
class ConvAddPreluKernel<P: PrecisionType>: Kernel, Computable {
var metalParam: MetalConvParam!
required init(device: MTLDevice, param: ConvAddPreluParam<P>) {
param.output.initTexture(device: device, inTranspose: [0, 2, 3, 1], computePrecision: computePrecision)
param.filter.initBuffer(device: device, precision: computePrecision)
param.y.initBuffer(device: device, precision: computePrecision)
param.alpha.initBuffer(device: device, precision: computePrecision)
if computePrecision == .Float16 {
if param.filter.width == 1 && param.filter.height == 1 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_half")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_half")
} else {
super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_half")
}
} else if param.filter.channel == 1 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_half")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_half")
} else {
super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_half")
}
} else if param.filter.width == 3 && param.filter.height == 3 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_half")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_half")
} else {
super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_half")
}
} else if param.filter.width == 1 && param.filter.height == 5 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_half")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_half")
} else {
super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_half")
}
} else if param.filter.width == 5 && param.filter.height == 1 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_half")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_half")
} else {
super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_half")
}
} else {
fatalError(" unsupport yet ")
}
} else if computePrecision == .Float32 {
if param.filter.width == 1 && param.filter.height == 1 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "conv_add_1x1_prelu_channel_float")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "conv_add_1x1_prelu_element_float")
} else {
super.init(device: device, inFunctionName: "conv_add_1x1_prelu_other_float")
}
} else if param.filter.channel == 1 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_channel_float")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_element_float")
} else {
super.init(device: device, inFunctionName: "depthwise_conv_add_3x3_prelu_other_float")
}
} else if param.filter.width == 3 && param.filter.height == 3 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "conv_add_3x3_prelu_channel_float")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "conv_add_3x3_prelu_element_float")
} else {
super.init(device: device, inFunctionName: "conv_add_3x3_prelu_other_float")
}
} else if param.filter.width == 1 && param.filter.height == 5 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "conv_add_5x1_prelu_channel_float")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "conv_add_5x1_prelu_element_float")
} else {
super.init(device: device, inFunctionName: "conv_add_5x1_prelu_other_float")
}
} else if param.filter.width == 5 && param.filter.height == 1 {
if param.mode == "channel" {
super.init(device: device, inFunctionName: "conv_add_1x5_prelu_channel_float")
} else if param.mode == "element" {
super.init(device: device, inFunctionName: "conv_add_1x5_prelu_element_float")
} else {
super.init(device: device, inFunctionName: "conv_add_1x5_prelu_other_float")
}
} else {
fatalError(" unsupport yet ")
}
} else {
fatalError()
}
let offsetY = (Int(param.dilations[1]) * (param.filter.height - 1) + 1)/2 - Int(param.paddings[1])
let offsetX = (Int(param.dilations[0]) * (param.filter.width - 1) + 1)/2 - Int(param.paddings[0])
// print(" function: \(functionName)")
// print("offset x: \(offsetX)")
// print("offset y: \(offsetY)")
let offsetZ = 0.0
let inMetalParam = MetalConvParam.init(offsetX: Int16(offsetX), offsetY: Int16(offsetY), offsetZ: Int16(offsetZ), strideX: UInt16(param.stride[0]), strideY: UInt16(param.stride[1]), dilationX: UInt16(param.dilations[0]), dilationY: UInt16(param.dilations[1]))
// print("metal param: ")
// print(inMetalParam)
metalParam = inMetalParam
}
func compute(commandBuffer: MTLCommandBuffer, param: ConvAddPreluParam<P>) throws {
// guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
// throw PaddleMobileError.predictError(message: " encode is nil")
// }
//
// encoder.setTexture(param.input.metalTexture, index: 0)
// encoder.setTexture(param.output.metalTexture, index: 1)
// encoder.setBytes(&metalParam, length: MemoryLayout<MetalConvParam>.size, index: 0)
// encoder.setBuffer(param.filter.buffer, offset: 0, index: 1)
// encoder.setBuffer(param.y.buffer, offset: 0, index: 2)
// encoder.setBuffer(param.alpha.buffer, offset: 0, index: 3)
// encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture)
// encoder.endEncoding()
}
}
/* 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
struct FlattenMetalParam {
var idim: (Int32, Int32, Int32, Int32)
var itrans: (Int32, Int32, Int32, Int32)
var odim: (Int32, Int32, Int32, Int32)
var otrans: (Int32, Int32, Int32, Int32)
}
class FlattenKernel<P: PrecisionType>: Kernel, Computable{
var metalParam: FlattenMetalParam
required init(device: MTLDevice, param: FlattenParam<P>) {
param.output.initTexture(device: device, computePrecision: computePrecision)
var id: [Int32] = [1, 1, 1, 1]
for i in 0..<param.input.tensorDim.cout() {
id[4-param.input.tensorDim.cout()+i] = Int32(param.input.tensorDim[i])
}
let it: [Int32] = param.input.transpose.map { Int32($0) }
var od: [Int32] = [1, 1, 1, 1]
for i in 0..<param.output.tensorDim.cout() {
od[4-param.output.tensorDim.cout()+i] = Int32(param.output.tensorDim[i])
}
let ot: [Int32] = param.output.transpose.map { Int32($0) }
metalParam = FlattenMetalParam.init(
idim: (id[0], id[1], id[2], id[3]),
itrans: (it[0], it[1], it[2], it[3]),
odim: (od[0], od[1], od[2], od[3]),
otrans: (ot[0], ot[1], ot[2], ot[3])
)
let irank = param.input.tensorDim.cout()
let orank = param.output.tensorDim.cout()
assert(orank == 2)
if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "reshape_\(irank)_2_float")
} else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "reshape_\(irank)_2_half")
} else {
fatalError()
}
}
func compute(commandBuffer: MTLCommandBuffer, param: FlattenParam<P>) throws {
guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
throw PaddleMobileError.predictError(message: " encoder is nil")
}
encoder.setTexture(param.input.metalTexture, index: 0)
encoder.setTexture(param.output.metalTexture, index: 1)
encoder.setBytes(&metalParam, length: MemoryLayout<ReshapeMetalParam>.size, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: param.output.metalTexture)
encoder.endEncoding()
}
}
...@@ -15,11 +15,41 @@ ...@@ -15,11 +15,41 @@
import Foundation import Foundation
class MulticlassNMSKernel<P: PrecisionType>: Kernel, Computable{ class MulticlassNMSKernel<P: PrecisionType>: Kernel, Computable{
let pipline1: MTLComputePipelineState
required init(device: MTLDevice, param: MulticlassNMSParam<P>) { required init(device: MTLDevice, param: MulticlassNMSParam<P>) {
super.init(device: device, inFunctionName: "place_holder")
param.middleOutput.initBuffer(device: device)
param.bboxOutput.initBuffer(device: device)
if computePrecision == .Float32 {
pipline1 = device.pipeLine(funcName: "nms_fetch_bbox", inPaddleMobileLib: true)
super.init(device: device, inFunctionName: "nms_fetch_result")
} else if computePrecision == .Float16 {
pipline1 = device.pipeLine(funcName: "nms_fetch_bbox_half", inPaddleMobileLib: true)
super.init(device: device, inFunctionName: "nms_fetch_result_half")
} else {
fatalError( " unsupport precision " )
}
} }
func compute(commandBuffer: MTLCommandBuffer, param: MulticlassNMSParam<P>) throws { func compute(commandBuffer: MTLCommandBuffer, param: MulticlassNMSParam<P>) throws {
guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
throw PaddleMobileError.predictError(message: " encode is nil")
}
encoder.setTexture(param.scores.metalTexture, index: 0)
encoder.setBuffer(param.middleOutput.resultBuffer!, offset: 0, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: param.scores.metalTexture)
encoder.endEncoding()
guard let encoderBox = commandBuffer.makeComputeCommandEncoder() else {
throw PaddleMobileError.predictError(message: " encode is nil")
}
encoderBox.setTexture(param.bboxes.metalTexture, index: 0)
encoderBox.setBuffer(param.bboxOutput.resultBuffer!, offset: 0, index: 0)
encoderBox.dispatch(computePipline: pipline1, outTexture: param.bboxes.metalTexture)
encoderBox.endEncoding()
} }
} }
...@@ -34,24 +34,44 @@ class PriorBoxKernel<P: PrecisionType>: Kernel, Computable{ ...@@ -34,24 +34,44 @@ class PriorBoxKernel<P: PrecisionType>: Kernel, Computable{
required init(device: MTLDevice, param: PriorBoxParam<P>) { required init(device: MTLDevice, param: PriorBoxParam<P>) {
param.output.initTexture(device: device, inTranspose: [2, 0, 1, 3], computePrecision: computePrecision) let originDim = param.output.tensorDim;
param.output.tensorDim = Dim.init(inDim: [1, originDim[0], originDim[1], originDim[2] * originDim[3]])
param.output.padToFourDim = Dim.init(inDim: [1, originDim[0], originDim[1], originDim[2] * originDim[3]])
param.output.initTexture(device: device, inTranspose: [0, 1, 2, 3], computePrecision: computePrecision)
param.outputVariances.initTexture(device: device, inTranspose: [2, 0, 1, 3], computePrecision: computePrecision) param.outputVariances.initTexture(device: device, inTranspose: [2, 0, 1, 3], computePrecision: computePrecision)
if computePrecision == .Float32 { if computePrecision == .Float32 {
if param.min_max_aspect_ratios_order {
super.init(device: device, inFunctionName: "prior_box_MinMaxAspectRatiosOrder")
} else {
super.init(device: device, inFunctionName: "prior_box") super.init(device: device, inFunctionName: "prior_box")
}
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
if param.min_max_aspect_ratios_order {
super.init(device: device, inFunctionName: "prior_box_MinMaxAspectRatiosOrder_half")
} else {
super.init(device: device, inFunctionName: "prior_box_half") super.init(device: device, inFunctionName: "prior_box_half")
}
} else { } else {
fatalError() fatalError()
} }
let n = 1
let h = param.output.dim[1]
let w = param.output.dim[2]
let c = param.output.dim[3] * param.output.dim[0]
param.output.dim = Dim.init(inDim: [n, h, w, c]) guard param.minSizes.count == 1 else {
param.output.transpose = [0, 1, 2, 3] fatalError(" need implement ")
}
// let n = 1
// let h = param.output.dim[1]
// let w = param.output.dim[2]
// let c = param.output.dim[3] * param.output.dim[0]
//
// param.output.dim = Dim.init(inDim: [n, h, w, c])
// param.output.transpose = [0, 1, 2, 3]
let imageWidth = Float32(param.inputImage.padToFourDim[3]) let imageWidth = Float32(param.inputImage.padToFourDim[3])
let imageHeight = Float32(param.inputImage.padToFourDim[2]) let imageHeight = Float32(param.inputImage.padToFourDim[2])
......
...@@ -49,10 +49,12 @@ class ReshapeKernel<P: PrecisionType>: Kernel, Computable{ ...@@ -49,10 +49,12 @@ class ReshapeKernel<P: PrecisionType>: Kernel, Computable{
odim: (od[0], od[1], od[2], od[3]), odim: (od[0], od[1], od[2], od[3]),
otrans: (ot[0], ot[1], ot[2], ot[3]) otrans: (ot[0], ot[1], ot[2], ot[3])
) )
let irank = param.input.tensorDim.cout()
let orank = param.output.tensorDim.cout()
if computePrecision == .Float32 { if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "reshape") super.init(device: device, inFunctionName: "reshape_\(irank)_\(orank)_float")
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "reshape_half") super.init(device: device, inFunctionName: "reshape_\(irank)_\(orank)_half")
} else { } else {
fatalError() fatalError()
} }
...@@ -81,15 +83,15 @@ class ReshapeKernel<P: PrecisionType>: Kernel, Computable{ ...@@ -81,15 +83,15 @@ class ReshapeKernel<P: PrecisionType>: Kernel, Computable{
encoder.endEncoding() encoder.endEncoding()
} }
func test(commandBuffer: MTLCommandBuffer, testParam: ReshapeTestParam) { // func test(commandBuffer: MTLCommandBuffer, testParam: ReshapeTestParam) {
guard let encoder = commandBuffer.makeComputeCommandEncoder() else { // guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
fatalError() // fatalError()
} // }
encoder.setTexture(testParam.inputTexture, index: 0) // encoder.setTexture(testParam.inputTexture, index: 0)
encoder.setTexture(testParam.outputTexture, index: 1) // encoder.setTexture(testParam.outputTexture, index: 1)
var pm: ReshapeMetalParam = testParam.param // var pm: ReshapeMetalParam = testParam.param
encoder.setBytes(&pm, length: MemoryLayout<ReshapeMetalParam>.size, index: 0) // encoder.setBytes(&pm, length: MemoryLayout<ReshapeMetalParam>.size, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: testParam.outputTexture) // encoder.dispatch(computePipline: pipline, outTexture: testParam.outputTexture)
encoder.endEncoding() // encoder.endEncoding()
} // }
} }
...@@ -19,19 +19,20 @@ struct ShapeMetalParam { ...@@ -19,19 +19,20 @@ struct ShapeMetalParam {
class ShapeKernel<P: PrecisionType>: Kernel, Computable{ class ShapeKernel<P: PrecisionType>: Kernel, Computable{
func compute(commandBuffer: MTLCommandBuffer, param: ShapeParam<P>) throws { func compute(commandBuffer: MTLCommandBuffer, param: ShapeParam<P>) throws {
guard let encoder = commandBuffer.makeComputeCommandEncoder() else { // print("shape compute")
throw PaddleMobileError.predictError(message: " encode is nil") // guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
} // throw PaddleMobileError.predictError(message: " encode is nil")
encoder.setTexture(param.output.metalTexture, index: 0) // }
encoder.endEncoding() // encoder.setTexture(param.output.metalTexture, index: 0)
// encoder.endEncoding()
} }
required init(device: MTLDevice, param: ShapeParam<P>) { required init(device: MTLDevice, param: ShapeParam<P>) {
param.output.initTexture(device: device, computePrecision: computePrecision) param.output.initTexture(device: device, computePrecision: computePrecision)
if computePrecision == .Float32 { if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "split") super.init(device: device, inFunctionName: "shape")
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "split_half") super.init(device: device, inFunctionName: "shape_half")
} else { } else {
fatalError() fatalError()
} }
......
...@@ -29,7 +29,7 @@ class SoftmaxKernel<P: PrecisionType>: Kernel, Computable{ ...@@ -29,7 +29,7 @@ class SoftmaxKernel<P: PrecisionType>: Kernel, Computable{
K: Int32(param.input.tensorDim[1]) K: Int32(param.input.tensorDim[1])
) )
if computePrecision == .Float32 { if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "softmax") super.init(device: device, inFunctionName: "softmax_float")
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "softmax_half") super.init(device: device, inFunctionName: "softmax_half")
} else { } else {
......
...@@ -15,23 +15,76 @@ ...@@ -15,23 +15,76 @@
import Foundation import Foundation
struct SplitMetalParam { struct SplitMetalParam {
var idim: (Int32, Int32, Int32, Int32) = (1, 1, 1, 1)
var axis: Int32 = 0
var offset: Int32 = 0
var trans: (Int32, Int32, Int32, Int32) = (0, 1, 2, 3)
var vdim: (Int32, Int32, Int32, Int32) = (0, 0, 0, 0)
} }
class SplitKernel<P: PrecisionType>: Kernel, Computable{ class SplitKernel<P: PrecisionType>: Kernel, Computable{
var smp: SplitMetalParam
func compute(commandBuffer: MTLCommandBuffer, param: SplitParam<P>) throws { func compute(commandBuffer: MTLCommandBuffer, param: SplitParam<P>) throws {
guard let encoder = commandBuffer.makeComputeCommandEncoder() else { guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
throw PaddleMobileError.predictError(message: " encode is nil") throw PaddleMobileError.predictError(message: " encode is nil")
} }
encoder.setTexture(param.output.metalTexture, index: 0) encoder.setTexture(param.input.metalTexture, index: 0)
for i in 0..<param.outputList.count {
encoder.setTexture(param.outputList[i].metalTexture, index: i + 1)
}
encoder.setBytes(&smp, length: MemoryLayout<SplitMetalParam>.size, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: param.input.metalTexture)
encoder.endEncoding() encoder.endEncoding()
} }
required init(device: MTLDevice, param: SplitParam<P>) { required init(device: MTLDevice, param: SplitParam<P>) {
param.output.initTexture(device: device, computePrecision: computePrecision) // param.output.initTexture(device: device, computePrecision: computePrecision)
let num = param.outputList.count
let rank = param.input.tensorDim.cout()
assert(num >= 2 && num <= 4)
for output in param.outputList {
output.initTexture(device: device, inTranspose: param.input.transpose, computePrecision: computePrecision)
}
smp = SplitMetalParam.init()
smp.idim = (Int32(param.input.dim[0]), Int32(param.input.dim[1]), Int32(param.input.dim[2]), Int32(param.input.dim[3]))
smp.axis = Int32(param.axis + param.input.dim.cout() - param.input.tensorDim.cout())
for i in 0..<4 {
if param.input.transpose[i] == smp.axis {
smp.axis = Int32(i)
break
}
}
smp.trans = (Int32(param.input.transpose[0]), Int32(param.input.transpose[1]), Int32(param.input.transpose[2]), Int32(param.input.transpose[3]))
var vdim: [Int32] = [0, 0, 0, 0]
for i in 0..<num {
vdim[i] = Int32(param.outputList[i].tensorDim[param.axis])
}
smp.vdim = (vdim[0], vdim[1], vdim[2], vdim[3])
var v = "normal"
if rank == 4 {
if smp.axis == 1 {
v = "y"
} else if smp.axis == 2 {
v = "x"
}
} else if rank == 3 {
if smp.axis == 2 {
v = "y"
} else if smp.axis == 3 {
v = "x"
}
} else if rank == 2 {
if smp.axis == 2 {
v = "y"
}
}
if v == "normal" {
fatalError("split unsupported")
}
if computePrecision == .Float32 { if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "split") super.init(device: device, inFunctionName: "split_\(rank)_\(num)_\(v)_float")
} else if computePrecision == .Float16 { } else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "split_half") super.init(device: device, inFunctionName: "split_\(rank)_\(num)_\(v)_half")
} else { } else {
fatalError() fatalError()
} }
......
...@@ -17,73 +17,52 @@ import Foundation ...@@ -17,73 +17,52 @@ import Foundation
struct TransposeMetalParam { struct TransposeMetalParam {
var iC: Int32 = 0 var iC: Int32 = 0
var oC: Int32 = 0 var oC: Int32 = 0
var i0: Int32 var axis: (Int32, Int32, Int32, Int32) = (0, 1, 2, 3)
var i1: Int32
var i2: Int32
var i3: Int32
init(_ i0: Int32, _ i1: Int32, _ i2: Int32, _ i3: Int32) {
self.i0 = i0
self.i1 = i1
self.i2 = i2
self.i3 = i3
}
init(_ axis: [Int]) {
self.init(Int32(axis[0]), Int32(axis[1]), Int32(axis[2]), Int32(axis[3]))
}
}
struct TransposeTestParam: TestParam {
let inputTexture: MTLTexture
let outputTexture: MTLTexture
let iC: Int
let oC: Int
let axis: [Int]
} }
class TransposeKernel<P: PrecisionType>: Kernel, Computable, Testable { class TransposeKernel<P: PrecisionType>: Kernel, Computable {
var metalParam: TransposeMetalParam = TransposeMetalParam.init()
required init(device: MTLDevice, param: TransposeParam<P>) { required init(device: MTLDevice, param: TransposeParam<P>) {
param.output.initTexture(device: device, inTranspose: [0, 1, 2, 3], computePrecision: computePrecision) param.output.initTexture(device: device, computePrecision: computePrecision)
let rank = param.input.tensorDim.cout()
if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "transpose_half")
} else if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "transpose")
} else {
fatalError()
}
var invT: [Int] = [0, 1, 2, 3]
for (i, v) in param.input.transpose.enumerated() {
invT[v] = i
}
var axis: [Int] = [0, 1, 2, 3] var axis: [Int] = [0, 1, 2, 3]
for i in 0..<param.axis.count { for i in 0..<param.axis.count {
axis[4-param.axis.count+i] = 4 - param.axis.count + Int(param.axis[i]) axis[4-rank+i] = 4 - rank + Int(param.axis[i])
} }
let realAxis = axis.map {invT[$0]}
var tmp = TransposeMetalParam.init(realAxis) var naxis: [Int] = [0, 0, 0, 0]
tmp.iC = Int32(param.input.dim[param.input.transpose[3]]) for i in 0..<4 {
tmp.oC = Int32(param.output.dim[3]) for j in 0..<4 {
if realAxis == [0, 1, 2, 3] { if param.input.transpose[j] == axis[i] {
// print("====> transpose! FAST :)") naxis[i] = j
} else { break
// print("====> transpose! SLOW :(")
} }
metalParam = tmp
} }
}
required init(device: MTLDevice, testParam: TransposeTestParam) { metalParam.iC = Int32(param.input.dim[param.input.transpose[3]])
metalParam.oC = Int32(param.output.dim[3])
metalParam.axis = (Int32(naxis[0]), Int32(naxis[1]), Int32(naxis[2]), Int32(naxis[3]))
var kernelFunc = "transpose_undefined"
if computePrecision == .Float16 { if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "transpose_half") if param.input.transpose == axis {
kernelFunc = "transpose_copy_half"
} else {
kernelFunc = "transpose_\(rank)_half"
}
} else if computePrecision == .Float32 { } else if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "transpose") if param.input.transpose == axis {
kernelFunc = "transpose_copy_float"
} else {
kernelFunc = "transpose_\(rank)_float"
}
} else { } else {
fatalError() fatalError()
} }
print("===========>", kernelFunc)
print(metalParam)
super.init(device: device, inFunctionName: kernelFunc)
} }
var metalParam: TransposeMetalParam!
func compute(commandBuffer: MTLCommandBuffer, param: TransposeParam<P>) throws { func compute(commandBuffer: MTLCommandBuffer, param: TransposeParam<P>) throws {
guard let encoder = commandBuffer.makeComputeCommandEncoder() else { guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
throw PaddleMobileError.predictError(message: " encode is nil") throw PaddleMobileError.predictError(message: " encode is nil")
...@@ -97,18 +76,4 @@ class TransposeKernel<P: PrecisionType>: Kernel, Computable, Testable { ...@@ -97,18 +76,4 @@ class TransposeKernel<P: PrecisionType>: Kernel, Computable, Testable {
} }
public func test(commandBuffer: MTLCommandBuffer, param: TransposeTestParam) { }
guard let encoder = commandBuffer.makeComputeCommandEncoder() else {
fatalError()
}
encoder.setTexture(param.inputTexture, index: 0)
encoder.setTexture(param.outputTexture, index: 1)
var tmp = TransposeMetalParam.init(param.axis)
tmp.iC = Int32(param.iC)
tmp.oC = Int32(param.oC)
encoder.setBytes(&tmp, length: MemoryLayout<TransposeMetalParam>.size, index: 0)
encoder.dispatch(computePipline: pipline, outTexture: param.outputTexture)
encoder.endEncoding()
}}
...@@ -15,28 +15,28 @@ ...@@ -15,28 +15,28 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
kernel void batchnorm_half(texture2d_array<half, access::read> inTexture [[texture(0)]], kernel void batchnorm(texture2d_array<float, access::read> inTexture [[texture(0)]],
texture2d_array<half, access::write> outTexture [[texture(1)]], texture2d_array<float, access::write> outTexture [[texture(1)]],
const device half4 * newScale [[buffer(0)]], const device float4 * nscale [[buffer(0)]],
const device half4 * newBias [[buffer(1)]], const device float4 * nbias [[buffer(1)]],
uint3 gid [[thread_position_in_grid]]) { uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() || if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() || gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) return; gid.z >= outTexture.get_array_size()) return;
const half4 input = inTexture.read(gid.xy, gid.z); const float4 input = inTexture.read(gid.xy, gid.z);
half4 output = input * newScale[gid.z] + newBias[gid.z]; float4 output = input * nscale[gid.z] + nbias[gid.z];
outTexture.write(output, gid.xy, gid.z); outTexture.write(output, gid.xy, gid.z);
} }
kernel void batchnorm(texture2d_array<float, access::read> inTexture [[texture(0)]], kernel void batchnorm_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
texture2d_array<float, access::write> outTexture [[texture(1)]], texture2d_array<half, access::write> outTexture [[texture(1)]],
const device float4 * newScale [[buffer(0)]], const device half4 * newScale [[buffer(0)]],
const device float4 * newBias [[buffer(1)]], const device half4 * newBias [[buffer(1)]],
uint3 gid [[thread_position_in_grid]]) { uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() || if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() || gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) return; gid.z >= outTexture.get_array_size()) return;
const float4 input = inTexture.read(gid.xy, gid.z); const half4 input = inTexture.read(gid.xy, gid.z);
float4 output = input * newScale[gid.z] + newBias[gid.z]; half4 output = input * newScale[gid.z] + newBias[gid.z];
outTexture.write(output, gid.xy, gid.z); outTexture.write(output, gid.xy, gid.z);
} }
#ifdef P
#define CONCAT2(a, b) a ## b
#define CONCAT2_(a, b) a ## _ ## b
#define FUNC(f, p) CONCAT2_(f, p)
#define VECTOR(p, n) CONCAT2(p, n)
kernel void FUNC(bilinear_interp, P)(texture2d_array<P, access::read> input [[texture(0)]],
texture2d_array<P, access::write> output [[texture(1)]],
constant bilinear_interp_param & pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
VECTOR(P, 4) r;
if ((input.get_width() == output.get_width()) && (input.get_height() == output.get_height())) {
r = input.read(gid.xy, gid.z);
} else {
P w = gid.x * pm.ratio_w;
P h = gid.y * pm.ratio_h;
uint w0 = w, h0 = h;
uint w1 = w0 + 1, h1 = h0 + 1;
P w1lambda = w - w0, h1lambda = h - h0;
P w2lambda = 1.0 - w1lambda, h2lambda = 1.0 - h1lambda;
if (w1 >= input.get_width()) w1 = w0;
if (h1 >= input.get_height()) h1 = h0;
VECTOR(P, 4) r0 = input.read(uint2(w0, h0), gid.z);
VECTOR(P, 4) r1 = input.read(uint2(w1, h0), gid.z);
VECTOR(P, 4) r2 = input.read(uint2(w0, h1), gid.z);
VECTOR(P, 4) r3 = input.read(uint2(w1, h1), gid.z);
r = h2lambda * (w2lambda * r0 + w1lambda * r1)
+ h1lambda * (w2lambda * r2 + w1lambda * r3);
}
output.write(r, gid.xy, gid.z);
}
#endif
...@@ -16,60 +16,14 @@ ...@@ -16,60 +16,14 @@
using namespace metal; using namespace metal;
struct bilinear_interp_param { struct bilinear_interp_param {
// int32_t out_h;
// int32_t out_w;
float ratio_h; float ratio_h;
float ratio_w; float ratio_w;
}; };
kernel void bilinear_interp(texture2d_array<float, access::read> input [[texture(0)]], #define P float
texture2d_array<float, access::write> output [[texture(2)]], #include "BilinearInterp.inc.metal"
constant bilinear_interp_param & pm [[buffer(0)]], #undef P
uint3 gid [[thread_position_in_grid]]) {
float4 r;
if ((input.get_width() == output.get_width()) && (input.get_height() == output.get_height())) {
r = input.read(gid.xy, gid.z);
} else {
float w = gid.x * pm.ratio_w;
float h = gid.y * pm.ratio_h;
uint w0 = w, h0 = h;
uint w1 = w0 + 1, h1 = h0 + 1;
float w1lambda = w - w0, h1lambda = h - h0;
float w2lambda = 1.0 - w1lambda, h2lambda = 1.0 - h1lambda;
if (w1 >= input.get_width()) w1 = w0;
if (h1 >= input.get_height()) h1 = h0;
float4 r0 = input.read(uint2(w0, h0), gid.z);
float4 r1 = input.read(uint2(w1, h0), gid.z);
float4 r2 = input.read(uint2(w0, h1), gid.z);
float4 r3 = input.read(uint2(w1, h1), gid.z);
r = h2lambda * (w2lambda * r0 + w1lambda * r1) + h1lambda * (w2lambda * r2 + w1lambda * r3);
}
output.write(r, gid.xy, gid.z);
}
kernel void bilinear_interp_half(texture2d_array<half, access::read> input [[texture(0)]], #define P half
texture2d_array<half, access::write> output [[texture(2)]], #include "BilinearInterp.inc.metal"
constant bilinear_interp_param & pm [[buffer(0)]], #undef P
uint3 gid [[thread_position_in_grid]]) {
half4 r;
if ((input.get_width() == output.get_width()) && (input.get_height() == output.get_height())) {
r = input.read(gid.xy, gid.z);
} else {
half w = gid.x * pm.ratio_w;
half h = gid.y * pm.ratio_h;
uint w0 = w, h0 = h;
uint w1 = w0 + 1, h1 = h0 + 1;
half w1lambda = w - w0, h1lambda = h - h0;
half w2lambda = 1.0 - w1lambda, h2lambda = 1.0 - h1lambda;
if (w1 >= input.get_width()) w1 = w0;
if (h1 >= input.get_height()) h1 = h0;
half4 r0 = input.read(uint2(w0, h0), gid.z);
half4 r1 = input.read(uint2(w1, h0), gid.z);
half4 r2 = input.read(uint2(w0, h1), gid.z);
half4 r3 = input.read(uint2(w1, h1), gid.z);
r = h2lambda * (w2lambda * r0 + w1lambda * r1) + h1lambda * (w2lambda * r2 + w1lambda * r3);
}
output.write(r, gid.xy, gid.z);
output.write(r, gid.xy, gid.z);
}
#ifdef P
#define CONCAT2(a, b) a ## b
#define CONCAT2_(a, b) a ## _ ## b
#define FUNC(f, p) CONCAT2_(f, p)
#define VECTOR(p, n) CONCAT2(p, n)
kernel void FUNC(boxcoder, P)(texture2d_array<P, access::read> priorBox [[texture(0)]],
texture2d_array<P, access::read> priorBoxVar [[texture(1)]],
texture2d_array<P, access::read> targetBox [[texture(2)]],
texture2d_array<P, access::write> output[[texture(3)]],
uint3 gid [[thread_position_in_grid]]) {
VECTOR(P, 4) p = priorBox.read(uint2(0, gid.x), gid.z);
VECTOR(P, 4) pv = priorBoxVar.read(uint2(0, gid.x), gid.z);
VECTOR(P, 4) t;
t[0] = targetBox.read(uint2(0, gid.x), gid.z)[0];
t[1] = targetBox.read(uint2(1, gid.x), gid.z)[0];
t[2] = targetBox.read(uint2(2, gid.x), gid.z)[0];
t[3] = targetBox.read(uint2(3, gid.x), gid.z)[0];
P px = (p.x + p.z) / 2;
P py = (p.y + p.w) / 2;
P pw = p.z - p.x;
P ph = p.w - p.y;
P tx = pv.x * t.x * pw + px;
P ty = pv.y * t.y * ph + py;
P tw = exp(pv.z * t.z) * pw;
P th = exp(pv.w * t.w) * ph;
VECTOR(P, 4) r;
r.x = tx - tw / 2;
r.y = ty - th / 2;
r.z = tx + tw / 2;
r.w = ty + th / 2;
output.write(r, gid.xy, gid.z);
}
#endif
...@@ -15,58 +15,9 @@ ...@@ -15,58 +15,9 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
kernel void boxcoder(texture2d_array<float, access::read> priorBox [[texture(0)]], #define P float
texture2d_array<float, access::read> priorBoxVar [[texture(1)]], #include "BoxCoder.inc.metal"
texture2d_array<float, access::read> targetBox [[texture(2)]], #undef P
texture2d_array<float, access::write> output[[texture(3)]], #define P half
uint3 gid [[thread_position_in_grid]]) { #include "BoxCoder.inc.metal"
float4 t = targetBox.read(gid.xy, gid.z); #undef P
float4 p = priorBox.read(gid.xy, gid.z);
float4 pv = priorBoxVar.read(gid.xy, gid.z);
float px = (p.x + p.z) / 2;
float py = (p.y + p.w) / 2;
float pw = p.z - p.x;
float ph = p.w - p.y;
float tx = pv.x * t.x * pw + px;
float ty = pv.y * t.y * ph + py;
float tw = exp(pv.z * t.z) * pw;
float th = exp(pv.w * t.w) * ph;
float4 r;
r.x = tx - tw / 2;
r.y = ty - th / 2;
r.z = tx + tw / 2;
r.w = ty + th / 2;
output.write(r, gid.xy, gid.z);
}
kernel void boxcoder_half(texture2d_array<half, access::read> priorBox [[texture(0)]],
texture2d_array<half, access::read> priorBoxVar [[texture(1)]],
texture2d_array<half, access::read> targetBox [[texture(2)]],
texture2d_array<half, access::write> output[[texture(3)]],
uint3 gid [[thread_position_in_grid]]) {
half4 t = targetBox.read(gid.xy, gid.z);
half4 p = priorBox.read(gid.xy, gid.z);
half4 pv = priorBoxVar.read(gid.xy, gid.z);
float px = (float(p.x) + float(p.z)) / 2;
float py = (float(p.y) + float(p.w)) / 2;
float pw = float(p.z) - float(p.x);
float ph = float(p.w) - float(p.y);
float tx = float(pv.x) * float(t.x) * pw + px;
float ty = float(pv.y) * float(t.y) * ph + py;
float tw = exp(float(pv.z) * float(t.z)) * pw;
float th = exp(float(pv.w) * float(t.w)) * ph;
float4 r;
r.x = tx - tw / 2;
r.y = ty - th / 2;
r.z = tx + tw / 2;
r.w = ty + th / 2;
output.write(half4(r), gid.xy, gid.z);
}
...@@ -15,6 +15,55 @@ ...@@ -15,6 +15,55 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
inline void xyzn2abcd_1(int xyzn[4], int abcd[4]) {
abcd[0] = abcd[1] = abcd[2] = 0;
abcd[3] = xyzn[0] * 4 + xyzn[3];
}
inline void xyzn2abcd_2(int xyzn[4], int abcd[4]) {
abcd[0] = abcd[1] = 0;
abcd[2] = xyzn[1];
abcd[3] = xyzn[0] * 4 + xyzn[3];
}
inline void xyzn2abcd_3(int xyzn[4], int abcd[4]) {
abcd[0] = 0;
abcd[3] = xyzn[0];
abcd[2] = xyzn[1];
abcd[1] = xyzn[2] * 4 + xyzn[3];
}
inline void xyzn2abcd_4(int C, int xyzn[4], int abcd[4]) {
abcd[2] = xyzn[0];
abcd[1] = xyzn[1];
uint t = xyzn[2] * 4 + xyzn[3];
abcd[0] = t / C;
abcd[3] = t % C;
}
inline void abcd2xyzn_1(int abcd[4], int xyzn[4]) {
xyzn[1] = xyzn[2] = 0;
xyzn[0] = abcd[3] / 4;
xyzn[1] = abcd[3] % 4;
}
inline void abcd2xyzn_2(int abcd[4], int xyzn[4]) {
xyzn[2] = 0;
xyzn[1] = abcd[2];
xyzn[0] = abcd[3] / 4;
xyzn[3] = abcd[3] % 4;
}
inline void abcd2xyzn_3(int abcd[4], int xyzn[4]) {
xyzn[0] = abcd[3];
xyzn[1] = abcd[2];
xyzn[2] = abcd[1] / 4;
xyzn[3] = abcd[1] % 4;
}
inline void abcd2xyzn_4(int C, int abcd[4], int xyzn[4]) {
xyzn[0] = abcd[2];
xyzn[1] = abcd[1];
uint t = abcd[0] * C + abcd[3];
xyzn[2] = t / 4;
xyzn[3] = t % 4;
}
inline void xyzn2abcd(int C, int xyzn[4], int abcd[4]) { inline void xyzn2abcd(int C, int xyzn[4], int abcd[4]) {
abcd[2] = xyzn[0]; abcd[2] = xyzn[0];
abcd[1] = xyzn[1]; abcd[1] = xyzn[1];
......
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <metal_stdlib>
#include "Common.metal"
using namespace metal;
struct ConcatParam {
int32_t odim[4];
int32_t axis;
int32_t offset;
int32_t trans[4];
int32_t vdim[6];
};
kernel void concat(texture2d_array<float, access::read> in0 [[texture(0)]],
texture2d_array<float, access::read> in1 [[texture(1)]],
texture2d_array<float, access::read> in2 [[texture(2)]],
texture2d_array<float, access::read> in3 [[texture(3)]],
texture2d_array<float, access::read> in4 [[texture(4)]],
texture2d_array<float, access::read> in5 [[texture(5)]],
texture2d_array<float, access::read> inx [[texture(6)]],
texture2d_array<float, access::write> out [[texture(7)]],
constant ConcatParam & pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
ConcatParam cp = pm;
int xyzn[4] = {int(gid.x), int(gid.y), int(gid.z), 0}, abcd[4], oxyzn[4];
float4 r;
for (int i = 0; i < 4; i++) {
xyzn[3] = i;
xyzn2abcd(cp.odim[3], xyzn, abcd);
int k = abcd[cp.axis] - cp.offset;
int j = 0;
if (k < 0) {
r[i] = inx.read(gid.xy, gid.z)[i];
} else {
for (; j < 6; j++) {
if (k < cp.vdim[j]) {
break;
}
k -= cp.vdim[j];
}
int ta = cp.odim[cp.axis];
abcd[cp.axis] = k;
cp.odim[cp.axis] = cp.vdim[j];
abcd2xyzn(cp.odim[3], abcd, oxyzn);
cp.odim[cp.axis] = ta;
switch (j) {
case 0: r[i] = in0.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 1: r[i] = in1.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 2: r[i] = in2.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 3: r[i] = in3.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 4: r[i] = in4.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 5: r[i] = in5.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
}
}
}
out.write(r, gid.xy, gid.z);
}
kernel void concat_half(texture2d_array<half, access::read> in0 [[texture(0)]],
texture2d_array<half, access::read> in1 [[texture(1)]],
texture2d_array<half, access::read> in2 [[texture(2)]],
texture2d_array<half, access::read> in3 [[texture(3)]],
texture2d_array<half, access::read> in4 [[texture(4)]],
texture2d_array<half, access::read> in5 [[texture(5)]],
texture2d_array<half, access::read> inx [[texture(6)]],
texture2d_array<half, access::write> out [[texture(7)]],
constant ConcatParam & pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
ConcatParam cp = pm;
int xyzn[4] = {int(gid.x), int(gid.y), int(gid.z), 0}, abcd[4], oxyzn[4];
half4 r;
for (int i = 0; i < 4; i++) {
xyzn[3] = i;
xyzn2abcd(cp.odim[3], xyzn, abcd);
int k = abcd[cp.axis] - cp.offset;
int j = 0;
if (k < 0) {
r[i] = inx.read(gid.xy, gid.z)[i];
} else {
for (; j < 6; j++) {
if (k < cp.vdim[j]) {
break;
}
k -= cp.vdim[j];
}
int ta = cp.odim[cp.axis];
abcd[cp.axis] = k;
cp.odim[cp.axis] = cp.vdim[j];
abcd2xyzn(cp.odim[3], abcd, oxyzn);
cp.odim[cp.axis] = ta;
switch (j) {
case 0: r[i] = in0.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 1: r[i] = in1.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 2: r[i] = in2.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 3: r[i] = in3.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 4: r[i] = in4.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 5: r[i] = in5.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
}
}
}
out.write(r, gid.xy, gid.z);
}
#ifdef P
#define CONCAT2(a, b) a ## b
#define CONCAT2_(a, b) a ## _ ## b
#define CONCAT3_(a, b, c) a ## _ ## b ## _ ## c
#define CONCAT4_(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d
#define CONCAT5_(a, b, c, d, e) a ## _ ## b ## _ ## c ## _ ## d ## _ ## e
#define FUNC(f, r, n, v, p) CONCAT5_(f, r, n, v, p)
#define VECTOR(p, n) CONCAT2(p, n)
#define FUNC_R(f, r) CONCAT2_(f, r)
#if V == VX
#define VV x
#elif V == VY
#define VV y
#elif V == VZ
#define VV z
#else
#define VV normal
#endif
#if V == VNORMAL
//kernel void FUNC(concat, R, N, normal, P)(array<texture2d_array<P, access::read>, N> in [[texture(0)]],
// texture2d_array<P, access::read> out_x [[texture(N)]],
// texture2d_array<P, access::write> out [[texture(N+1)]],
// constant ConcatParam & pm [[buffer(0)]],
// uint3 gid [[thread_position_in_grid]]) {
//}
kernel void FUNC(concat, R, N, VV, P)(texture2d_array<P, access::read> in0 [[texture(0)]],
texture2d_array<P, access::read> in1 [[texture(1)]],
#if N >= 3
texture2d_array<P, access::read> in2 [[texture(2)]],
#endif
#if N >= 4
texture2d_array<P, access::read> in3 [[texture(3)]],
#endif
#if N >= 5
texture2d_array<P, access::read> in4 [[texture(4)]],
#endif
#if N >= 6
texture2d_array<P, access::read> in5 [[texture(5)]],
#endif
texture2d_array<P, access::read> inx [[texture(N)]],
texture2d_array<P, access::write> out [[texture(N+1)]],
constant ConcatParam & pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
ConcatParam cp = pm;
int xyzn[4] = {int(gid.x), int(gid.y), int(gid.z), 0}, abcd[4], oxyzn[4];
VECTOR(P, 4) r = inx.read(gid.xy, gid.z);
for (int i = 0; i < 4; i++) {
xyzn[3] = i;
#if R == 4
xyzn2abcd_4(cp.odim[3], xyzn, abcd);
#else
FUNC_R(xyzn2abcd, R)(xyzn, abcd);
#endif
int k = abcd[cp.axis] - cp.offset;
if (k < 0) continue;
int j = 0;
for (; j < N; j++) {
if (k < cp.vdim[j]) {
break;
}
k -= cp.vdim[j];
}
if (k > cp.vdim[N-1]) {
continue;
}
int ta = cp.odim[cp.axis];
abcd[cp.axis] = k;
cp.odim[cp.axis] = cp.vdim[j];
#if R == 4
abcd2xyzn_4(cp.odim[3], abcd, oxyzn);
#else
FUNC_R(abcd2xyzn, R)(abcd, oxyzn);
#endif
cp.odim[cp.axis] = ta;
switch (j) {
case 0: r[i] = in0.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
case 1: r[i] = in1.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
#if N >= 3
case 2: r[i] = in2.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
#endif
#if N >= 4
case 3: r[i] = in3.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
#endif
#if N >= 5
case 4: r[i] = in4.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
#endif
#if N >= 6
case 5: r[i] = in5.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2])[oxyzn[3]]; break;
#endif
}
}
out.write(r, gid.xy, gid.z);
}
#endif // V == NORMAL
#if V == VX
kernel void FUNC(concat, R, N, VV, P)(texture2d_array<P, access::read> in0 [[texture(0)]],
texture2d_array<P, access::read> in1 [[texture(1)]],
#if N >= 3
texture2d_array<P, access::read> in2 [[texture(2)]],
#endif // N >= 3
#if N >= 4
texture2d_array<P, access::read> in3 [[texture(3)]],
#endif // N >= 4
#if N >= 5
texture2d_array<P, access::read> in4 [[texture(4)]],
#endif // N >= 5
#if N >= 6
texture2d_array<P, access::read> in5 [[texture(5)]],
#endif // N >= 6
texture2d_array<P, access::write> out [[texture(N)]],
constant ConcatParam & pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
int x = gid.x - pm.offset;
if (x < 0) return;
if (x < pm.vdim[0]) {
VECTOR(P, 4) r = in0.read(gid.xy, gid.z);
out.write(r, gid.xy, gid.z);
return;
}
x -= pm.vdim[0];
if (x < pm.vdim[1]) {
VECTOR(P, 4) r = in1.read(uint2(x, gid.y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#if N >= 3
x -= pm.vdim[1];
if (x < pm.vdim[2]) {
VECTOR(P, 4) r = in2.read(uint2(x, gid.y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 3
#if N >= 4
x -= pm.vdim[2];
if (x < pm.vdim[3]) {
VECTOR(P, 4) r = in3.read(uint2(x, gid.y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 4
#if N >= 5
x -= pm.vdim[3];
if (x < pm.vdim[4]) {
VECTOR(P, 4) r = in4.read(uint2(x, gid.y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 5
#if N >= 6
x -= pm.vdim[4];
if (x < pm.vdim[5]) {
VECTOR(P, 4) r = in5.read(uint2(x, gid.y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 6
}
#endif // V == VX
#if V == VY
kernel void FUNC(concat, R, N, VV, P)(texture2d_array<P, access::read> in0 [[texture(0)]],
texture2d_array<P, access::read> in1 [[texture(1)]],
#if N >= 3
texture2d_array<P, access::read> in2 [[texture(2)]],
#endif // N >= 3
#if N >= 4
texture2d_array<P, access::read> in3 [[texture(3)]],
#endif // N >= 4
#if N >= 5
texture2d_array<P, access::read> in4 [[texture(4)]],
#endif // N >= 5
#if N >= 6
texture2d_array<P, access::read> in5 [[texture(5)]],
#endif // N >= 6
texture2d_array<P, access::write> out [[texture(N)]],
constant ConcatParam & pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
int y = gid.y - pm.offset;
if (y < 0) return;
if (y < pm.vdim[0]) {
VECTOR(P, 4) r = in0.read(gid.xy, gid.z);
out.write(r, gid.xy, gid.z);
return;
}
y -= pm.vdim[0];
if (y < pm.vdim[1]) {
VECTOR(P, 4) r = in1.read(uint2(gid.x, y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#if N >= 3
y -= pm.vdim[1];
if (y < pm.vdim[2]) {
VECTOR(P, 4) r = in2.read(uint2(gid.x, y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 3
#if N >= 4
y -= pm.vdim[2];
if (y < pm.vdim[3]) {
VECTOR(P, 4) r = in3.read(uint2(gid.x, y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 4
#if N >= 5
y -= pm.vdim[3];
if (y < pm.vdim[4]) {
VECTOR(P, 4) r = in4.read(uint2(gid.x, y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 5
#if N >= 6
y -= pm.vdim[4];
if (y < pm.vdim[5]) {
VECTOR(P, 4) r = in5.read(uint2(gid.x, y), gid.z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 6
}
#endif // V == VY
#if V == VZ
kernel void FUNC(concat, R, N, VV, P)(texture2d_array<P, access::read> in0 [[texture(0)]],
texture2d_array<P, access::read> in1 [[texture(1)]],
#if N >= 3
texture2d_array<P, access::read> in2 [[texture(2)]],
#endif // N >= 3
#if N >= 4
texture2d_array<P, access::read> in3 [[texture(3)]],
#endif // N >= 4
#if N >= 5
texture2d_array<P, access::read> in4 [[texture(4)]],
#endif // N >= 5
#if N >= 6
texture2d_array<P, access::read> in5 [[texture(5)]],
#endif // N >= 6
texture2d_array<P, access::write> out [[texture(N)]],
constant ConcatParam & pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
int z = gid.z - pm.offset;
if (z < 0) return;
if (z < pm.vdim[0]) {
VECTOR(P, 4) r = in0.read(gid.xy, gid.z);
out.write(r, gid.xy, gid.z);
return;
}
z -= pm.vdim[0];
if (z < pm.vdim[1]) {
VECTOR(P, 4) r = in1.read(gid.xy, z);
out.write(r, gid.xy, gid.z);
return;
}
#if N >= 3
z -= pm.vdim[1];
if (z < pm.vdim[2]) {
VECTOR(P, 4) r = in2.read(gid.xy, z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 3
#if N >= 4
z -= pm.vdim[2];
if (z < pm.vdim[3]) {
VECTOR(P, 4) r = in3.read(gid.xy, z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 4
#if N >= 5
z -= pm.vdim[3];
if (z < pm.vdim[4]) {
VECTOR(P, 4) r = in4.read(gid.xy, z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 5
#if N >= 6
z -= pm.vdim[4];
if (z < pm.vdim[5]) {
VECTOR(P, 4) r = in5.read(gid.xy, z);
out.write(r, gid.xy, gid.z);
return;
}
#endif // N >= 6
}
#endif // V == VZ
#undef VV
#endif // #ifdef P
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <metal_stdlib>
#include "Common.metal"
using namespace metal;
struct ConcatParam {
int32_t odim[4];
int32_t axis;
int32_t offset;
int32_t trans[4];
int32_t vdim[6];
};
#define VNORMAL 1
#define VX 2
#define VY 3
#define VZ 4
// >> fast mode
// only support concat_{2,3,4}_{2,3,4,5,6}_y_{float,half}
// only support concat_{3,4}_{2,3,4,5,6}_x_{float,half}
// only support concat_{1,2,3,4}_{2,3,4,5,6}_z_{float,half}
// >> normal mode (loop mode)
// ssd-ar: (R=4, N=3, V=z), (R=3, N=2, V=y), (R=2, N=5, V=x), (R=3, N=5, V=x)
// ssd: (R=2, N=6, V=y), (R=3, N=6, V=y)
// genet: (R=4, N=2, V=normal)
// ssd-ar: (R=3, N=5, V=x)
#define V VX
#define R 3
#define N 5
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
// ssd-ar: (R=2, N=5, V=x)
#define V VX
#define R 2
#define N 5
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
// ssd-ar: (R=3, N=2, V=y)
#define V VY
#define R 3
#define N 2
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
// ssd-ar: (R=4, N=3, V=z)
#define V VZ
#define R 4
#define N 3
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
// ssd: (R=2, N=6, V=y)
#define V VY
#define R 2
#define N 6
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
// ssd: (R=3, N=6, V=y)
#define V VY
#define R 3
#define N 6
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
#define V VNORMAL
#define R 4
#define N 2
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
#define V VY
#define R 2
#define N 2
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
#define V VY
#define R 2
#define N 5
#define P float
#include "ConcatKernel.inc.metal"
#undef P
#define P half
#include "ConcatKernel.inc.metal"
#undef P
#undef N
#undef R
#undef V
...@@ -17,13 +17,14 @@ ...@@ -17,13 +17,14 @@
using namespace metal; using namespace metal;
kernel void conv_add_batch_norm_relu_1x1_half(texture2d_array<half, access::sample> inTexture [[texture(0)]], kernel void conv_add_batch_norm_relu_1x1_half(
texture2d_array<half, access::sample> inTexture [[texture(0)]],
texture2d_array<half, access::write> outTexture [[texture(1)]], texture2d_array<half, access::write> outTexture [[texture(1)]],
constant MetalConvParam &param [[buffer(0)]], constant MetalConvParam &param [[buffer(0)]],
const device half4 *weights [[buffer(1)]], const device half4 *weights [[buffer(1)]],
const device half4 *biase [[buffer(2)]], const device half4 *biase [[buffer(2)]],
const device float4 *new_scale [[buffer(3)]], const device half4 *new_scale [[buffer(3)]],
const device float4 *new_biase [[buffer(4)]], const device half4 *new_biase [[buffer(4)]],
uint3 gid [[thread_position_in_grid]]) { uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() || if (gid.x >= outTexture.get_width() ||
...@@ -41,7 +42,7 @@ kernel void conv_add_batch_norm_relu_1x1_half(texture2d_array<half, access::samp ...@@ -41,7 +42,7 @@ kernel void conv_add_batch_norm_relu_1x1_half(texture2d_array<half, access::samp
uint input_arr_size = inTexture.get_array_size(); uint input_arr_size = inTexture.get_array_size();
uint weithTo = gid.z * kernelHXW * input_arr_size * 4; uint weithTo = gid.z * kernelHXW * input_arr_size * 4;
half4 output = half4(0.0); float4 output = float4(0.0);
half4 input; half4 input;
for (uint i = 0; i < input_arr_size; ++i) { for (uint i = 0; i < input_arr_size; ++i) {
...@@ -58,18 +59,18 @@ kernel void conv_add_batch_norm_relu_1x1_half(texture2d_array<half, access::samp ...@@ -58,18 +59,18 @@ kernel void conv_add_batch_norm_relu_1x1_half(texture2d_array<half, access::samp
half4 weight_w = weights[weithTo + 3 * kernelHXW * input_arr_size + i]; half4 weight_w = weights[weithTo + 3 * kernelHXW * input_arr_size + i];
output.w += dot(input, weight_w); output.w += dot(input, weight_w);
} }
output = fmax((output + float4(biase[gid.z])) * float4(new_scale[gid.z]) + float4(new_biase[gid.z]), 0.0);
output = half4(fmax((float4(output) + float4(biase[gid.z])) * new_scale[gid.z] + new_biase[gid.z], 0.0)); outTexture.write(half4(output), gid.xy, gid.z);
outTexture.write(output, gid.xy, gid.z);
} }
kernel void conv_add_batch_norm_relu_3x3_half(texture2d_array<half, access::sample> inTexture [[texture(0)]], kernel void conv_add_batch_norm_relu_3x3_half(
texture2d_array<half, access::sample> inTexture [[texture(0)]],
texture2d_array<half, access::write> outTexture [[texture(1)]], texture2d_array<half, access::write> outTexture [[texture(1)]],
constant MetalConvParam &param [[buffer(0)]], constant MetalConvParam &param [[buffer(0)]],
const device half4 *weights [[buffer(1)]], const device half4 *weights [[buffer(1)]],
const device half4 *biase [[buffer(2)]], const device half4 *biase [[buffer(2)]],
const device float4 *new_scale [[buffer(3)]], const device half4 *new_scale [[buffer(3)]],
const device float4 *new_biase [[buffer(4)]], const device half4 *new_biase [[buffer(4)]],
uint3 gid [[thread_position_in_grid]]) { uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() || if (gid.x >= outTexture.get_width() ||
...@@ -86,7 +87,7 @@ kernel void conv_add_batch_norm_relu_3x3_half(texture2d_array<half, access::samp ...@@ -86,7 +87,7 @@ kernel void conv_add_batch_norm_relu_3x3_half(texture2d_array<half, access::samp
uint input_arr_size = inTexture.get_array_size(); uint input_arr_size = inTexture.get_array_size();
uint weithTo = gid.z * kernelHXW * input_arr_size * 4; uint weithTo = gid.z * kernelHXW * input_arr_size * 4;
half4 output = half4(0.0); float4 output = float4(0.0);
half4 input[9]; half4 input[9];
for (uint i = 0; i < input_arr_size; ++i) { for (uint i = 0; i < input_arr_size; ++i) {
...@@ -113,18 +114,18 @@ kernel void conv_add_batch_norm_relu_3x3_half(texture2d_array<half, access::samp ...@@ -113,18 +114,18 @@ kernel void conv_add_batch_norm_relu_3x3_half(texture2d_array<half, access::samp
output.w += dot(input[j], weight_w); output.w += dot(input[j], weight_w);
} }
} }
output = half4(fmax((float4(output) + float4(biase[gid.z])) * new_scale[gid.z] + new_biase[gid.z], 0.0)); output = fmax((output + float4(biase[gid.z])) * float4(new_scale[gid.z]) + float4(new_biase[gid.z]), 0.0);
outTexture.write(output, gid.xy, gid.z); outTexture.write(half4(output), gid.xy, gid.z);
} }
kernel void depthwise_conv_add_batch_norm_relu_3x3_half(
kernel void depthwise_conv_add_batch_norm_relu_3x3_half(texture2d_array<half, access::sample> inTexture [[texture(0)]], texture2d_array<half, access::sample> inTexture [[texture(0)]],
texture2d_array<half, access::write> outTexture [[texture(1)]], texture2d_array<half, access::write> outTexture [[texture(1)]],
constant MetalConvParam &param [[buffer(0)]], constant MetalConvParam &param [[buffer(0)]],
const device half *weights [[buffer(1)]], const device half *weights [[buffer(1)]],
const device half4 *biase [[buffer(2)]], const device half4 *biase [[buffer(2)]],
const device float4 *new_scale [[buffer(3)]], const device half4 *new_scale [[buffer(3)]],
const device float4 *new_biase [[buffer(4)]], const device half4 *new_biase [[buffer(4)]],
uint3 gid [[thread_position_in_grid]]) { uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() || if (gid.x >= outTexture.get_width() ||
...@@ -138,7 +139,7 @@ kernel void depthwise_conv_add_batch_norm_relu_3x3_half(texture2d_array<half, ac ...@@ -138,7 +139,7 @@ kernel void depthwise_conv_add_batch_norm_relu_3x3_half(texture2d_array<half, ac
constexpr sampler sample(coord::pixel, filter::nearest, address::clamp_to_zero); constexpr sampler sample(coord::pixel, filter::nearest, address::clamp_to_zero);
const uint kernelHXW = 9; const uint kernelHXW = 9;
uint weithTo = gid.z * kernelHXW * 4; uint weithTo = gid.z * kernelHXW * 4;
half4 output = half4(0.0); float4 output = float4(0.0);
half4 inputs[9]; half4 inputs[9];
inputs[0] = inTexture.sample(sample, float2(posInInput.x - 1, posInInput.y - 1), output_slice); inputs[0] = inTexture.sample(sample, float2(posInInput.x - 1, posInInput.y - 1), output_slice);
inputs[1] = inTexture.sample(sample, float2(posInInput.x, posInInput.y - 1), output_slice); inputs[1] = inTexture.sample(sample, float2(posInInput.x, posInInput.y - 1), output_slice);
...@@ -156,11 +157,12 @@ kernel void depthwise_conv_add_batch_norm_relu_3x3_half(texture2d_array<half, ac ...@@ -156,11 +157,12 @@ kernel void depthwise_conv_add_batch_norm_relu_3x3_half(texture2d_array<half, ac
output.z += input.z * weights[weithTo + 2 * kernelHXW + j]; output.z += input.z * weights[weithTo + 2 * kernelHXW + j];
output.w += input.w * weights[weithTo + 3 * kernelHXW + j]; output.w += input.w * weights[weithTo + 3 * kernelHXW + j];
} }
output = half4(fmax((float4(output) + float4(biase[gid.z])) * new_scale[gid.z] + new_biase[gid.z], 0.0)); output = fmax((output + float4(biase[gid.z])) * float4(new_scale[gid.z]) + float4(new_biase[gid.z]), 0.0);
outTexture.write(output, gid.xy, gid.z); outTexture.write(half4(output), gid.xy, gid.z);
} }
/*---------------------------------------------*/ /*---------------------------------------------*/
......
/* 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. */
#ifdef P
#include "Macro.metal"
#pragma mark - convAdd
kernel void FUNC3_(conv_add_1x1, PRELU_TYPE, P)(texture2d_array<P, access::sample> inTexture [[texture(0)]],
texture2d_array<P, access::write> outTexture [[texture(1)]],
constant MetalConvParam &param [[buffer(0)]],
const device VECTOR(P, 4) *weights [[buffer(1)]],
const device VECTOR(P, 4) *biase [[buffer(2)]],
#ifdef PRELU_CHANNEL
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_ELEMENT
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_OTHER
const device P *alpha [[buffer(3)]],
#endif
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) {
return;
}
ushort2 stride = ushort2(param.strideX, param.strideY);
ushort2 posInInput = ushort2(gid.xy) * stride + ushort2(param.offsetX, param.offsetY);
constexpr sampler sample(coord::pixel, filter::nearest, address::clamp_to_zero);
const uint kernelHXW = 1;
uint input_arr_size = inTexture.get_array_size();
uint weithTo = gid.z * kernelHXW * input_arr_size * 4;
float4 output = float4(0.0);
VECTOR(P, 4) input;
for (uint i = 0; i < input_arr_size; ++i) {
input = inTexture.sample(sample,float2(posInInput.x, posInInput.y), i);
VECTOR(P, 4) weight_x = weights[weithTo + 0 * kernelHXW * input_arr_size + i];
output.x += dot(input, weight_x);
VECTOR(P, 4) weight_y = weights[weithTo + 1 * kernelHXW * input_arr_size + i];
output.y += dot(input, weight_y);
VECTOR(P, 4) weight_z = weights[weithTo + 2 * kernelHXW * input_arr_size + i];
output.z += dot(input, weight_z);
VECTOR(P, 4) weight_w = weights[weithTo + 3 * kernelHXW * input_arr_size + i];
output.w += dot(input, weight_w);
}
output = output + float4(biase[gid.z]);
#ifdef PRELU_CHANNEL
VECTOR(P, 4) alpha_value = alpha[gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_ELEMENT
int alpha_to = (gid.y * outTexture.get_width() + gid.x) * outTexture.get_array_size();
VECTOR(P, 4) alpha_value = alpha[alpha_to + gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_OTHER
P alpha_value = alpha[0];
output.x = output.x > 0 ? output.x : (alpha_value * output.x);
output.y = output.y > 0 ? output.y : (alpha_value * output.y);
output.z = output.z > 0 ? output.z : (alpha_value * output.z);
output.w = output.w > 0 ? output.w : (alpha_value * output.w);
#endif
outTexture.write(VECTOR(P, 4)(output), gid.xy, gid.z);
}
kernel void FUNC3_(conv_add_3x3, PRELU_TYPE, P)(texture2d_array<P, access::sample> inTexture [[texture(0)]],
texture2d_array<P, access::write> outTexture [[texture(1)]],
constant MetalConvParam &param [[buffer(0)]],
const device VECTOR(P, 4) *weights [[buffer(1)]],
const device VECTOR(P, 4) *biase [[buffer(2)]],
#ifdef PRELU_CHANNEL
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_ELEMENT
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_OTHER
const device P *alpha [[buffer(3)]],
#endif
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) {
return;
}
ushort2 stride = ushort2(param.strideX, param.strideY);
const ushort2 posInInput = ushort2(gid.xy) * stride + ushort2(param.offsetX, param.offsetY);
constexpr sampler sample(coord::pixel, filter::nearest, address::clamp_to_zero);
const uint kernelHXW = 9;
uint input_arr_size = inTexture.get_array_size();
uint weithTo = gid.z * kernelHXW * input_arr_size * 4;
float4 output = float4(0.0);
ushort dilation_x = param.dilationX;
ushort dilation_y = param.dilationY;
VECTOR(P, 4) input[9];
for (uint i = 0; i < input_arr_size; ++i) {
input[0] = inTexture.sample(sample, float2(posInInput.x - dilation_x, posInInput.y - dilation_y), i);
input[1] = inTexture.sample(sample, float2(posInInput.x, posInInput.y - dilation_y), i);
input[2] = inTexture.sample(sample, float2(posInInput.x + dilation_x, posInInput.y - dilation_y), i);
input[3] = inTexture.sample(sample, float2(posInInput.x - dilation_x, posInInput.y), i);
input[4] = inTexture.sample(sample, float2(posInInput.x, posInInput.y), i);
input[5] = inTexture.sample(sample, float2(posInInput.x + dilation_x, posInInput.y), i);
input[6] = inTexture.sample(sample, float2(posInInput.x - dilation_x, posInInput.y + dilation_y), i);
input[7] = inTexture.sample(sample, float2(posInInput.x, posInInput.y + dilation_y), i);
input[8] = inTexture.sample(sample, float2(posInInput.x + dilation_x, posInInput.y + dilation_y), i);
for (int j = 0; j < 9; ++j) {
VECTOR(P, 4) weight_x = weights[weithTo + 0 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.x += dot(input[j], weight_x);
VECTOR(P, 4) weight_y = weights[weithTo + 1 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.y += dot(input[j], weight_y);
VECTOR(P, 4) weight_z = weights[weithTo + 2 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.z += dot(input[j], weight_z);
VECTOR(P, 4) weight_w = weights[weithTo + 3 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.w += dot(input[j], weight_w);
}
}
output = output + float4(biase[gid.z]);
#ifdef PRELU_CHANNEL
VECTOR(P, 4) alpha_value = alpha[gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_ELEMENT
int alpha_to = (gid.y * outTexture.get_width() + gid.x) * outTexture.get_array_size();
VECTOR(P, 4) alpha_value = alpha[alpha_to + gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_OTHER
P alpha_value = alpha[0];
output.x = output.x > 0 ? output.x : (alpha_value * output.x);
output.y = output.y > 0 ? output.y : (alpha_value * output.y);
output.z = output.z > 0 ? output.z : (alpha_value * output.z);
output.w = output.w > 0 ? output.w : (alpha_value * output.w);
#endif
outTexture.write(VECTOR(P, 4)(output), gid.xy, gid.z);
}
kernel void FUNC3_(conv_add_5x1, PRELU_TYPE, P)(texture2d_array<P, access::sample> inTexture [[texture(0)]],
texture2d_array<P, access::write> outTexture [[texture(1)]],
constant MetalConvParam &param [[buffer(0)]],
const device VECTOR(P, 4) *weights [[buffer(1)]],
const device VECTOR(P, 4) *biase [[buffer(2)]],
#ifdef PRELU_CHANNEL
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_ELEMENT
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_OTHER
const device P *alpha [[buffer(3)]],
#endif
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) {
return;
}
ushort2 stride = ushort2(param.strideX, param.strideY);
const ushort2 posInInput = ushort2(gid.xy) * stride + ushort2(param.offsetX, param.offsetY);
constexpr sampler sample(coord::pixel, filter::nearest, address::clamp_to_zero);
const uint kernelHXW = 5;
uint input_arr_size = inTexture.get_array_size();
uint weithTo = gid.z * kernelHXW * input_arr_size * 4;
float4 output = float4(biase[gid.z]);;
ushort dilation_y = param.dilationY;
VECTOR(P, 4) input[5];
for (uint i = 0; i < input_arr_size; ++i) {
input[0] = inTexture.sample(sample, float2(posInInput.x, posInInput.y - 2 * dilation_y), i);
input[1] = inTexture.sample(sample, float2(posInInput.x, posInInput.y - dilation_y), i);
input[2] = inTexture.sample(sample, float2(posInInput.x, posInInput.y), i);
input[3] = inTexture.sample(sample, float2(posInInput.x, posInInput.y + dilation_y), i);
input[4] = inTexture.sample(sample, float2(posInInput.x, posInInput.y + 2 * dilation_y), i);
for (int j = 0; j < 5; ++j) {
VECTOR(P, 4) weight_x = weights[weithTo + 0 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.x += dot(input[j], weight_x);
VECTOR(P, 4) weight_y = weights[weithTo + 1 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.y += dot(input[j], weight_y);
VECTOR(P, 4) weight_z = weights[weithTo + 2 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.z += dot(input[j], weight_z);
VECTOR(P, 4) weight_w = weights[weithTo + 3 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.w += dot(input[j], weight_w);
}
}
#ifdef PRELU_CHANNEL
VECTOR(P, 4) alpha_value = alpha[gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_ELEMENT
int alpha_to = (gid.y * outTexture.get_width() + gid.x) * outTexture.get_array_size();
VECTOR(P, 4) alpha_value = alpha[alpha_to + gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_OTHER
P alpha_value = alpha[0];
output.x = output.x > 0 ? output.x : (alpha_value * output.x);
output.y = output.y > 0 ? output.y : (alpha_value * output.y);
output.z = output.z > 0 ? output.z : (alpha_value * output.z);
output.w = output.w > 0 ? output.w : (alpha_value * output.w);
#endif
outTexture.write(VECTOR(P, 4)(output), gid.xy, gid.z);
}
kernel void FUNC3_(conv_add_1x5, PRELU_TYPE, P)(texture2d_array<P, access::sample> inTexture [[texture(0)]],
texture2d_array<P, access::write> outTexture [[texture(1)]],
constant MetalConvParam &param [[buffer(0)]],
const device VECTOR(P, 4) *weights [[buffer(1)]],
const device VECTOR(P, 4) *biase [[buffer(2)]],
#ifdef PRELU_CHANNEL
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_ELEMENT
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_OTHER
const device P *alpha [[buffer(3)]],
#endif
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) {
return;
}
ushort2 stride = ushort2(param.strideX, param.strideY);
const ushort2 posInInput = ushort2(gid.xy) * stride + ushort2(param.offsetX, param.offsetY);
constexpr sampler sample(coord::pixel, filter::nearest, address::clamp_to_zero);
const uint kernelHXW = 5;
uint input_arr_size = inTexture.get_array_size();
uint weithTo = gid.z * kernelHXW * input_arr_size * 4;
float4 output = float4(biase[gid.z]);
ushort dilation_x = param.dilationX;
VECTOR(P, 4) input[5];
for (uint i = 0; i < input_arr_size; ++i) {
input[0] = inTexture.sample(sample, float2(posInInput.x - 2 * dilation_x, posInInput.y), i);
input[1] = inTexture.sample(sample, float2(posInInput.x - dilation_x, posInInput.y), i);
input[2] = inTexture.sample(sample, float2(posInInput.x, posInInput.y), i);
input[3] = inTexture.sample(sample, float2(posInInput.x + dilation_x, posInInput.y), i);
input[4] = inTexture.sample(sample, float2(posInInput.x + 2 * dilation_x, posInInput.y), i);
for (int j = 0; j < 5; ++j) {
VECTOR(P, 4) weight_x = weights[weithTo + 0 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.x += dot(input[j], weight_x);
VECTOR(P, 4) weight_y = weights[weithTo + 1 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.y += dot(input[j], weight_y);
VECTOR(P, 4) weight_z = weights[weithTo + 2 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.z += dot(input[j], weight_z);
VECTOR(P, 4) weight_w = weights[weithTo + 3 * kernelHXW * input_arr_size + j * input_arr_size + i];
output.w += dot(input[j], weight_w);
}
}
#ifdef PRELU_CHANNEL
VECTOR(P, 4) alpha_value = alpha[gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_ELEMENT
int alpha_to = (gid.y * outTexture.get_width() + gid.x) * outTexture.get_array_size();
VECTOR(P, 4) alpha_value = alpha[alpha_to + gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_OTHER
P alpha_value = alpha[0];
output.x = output.x > 0 ? output.x : (alpha_value * output.x);
output.y = output.y > 0 ? output.y : (alpha_value * output.y);
output.z = output.z > 0 ? output.z : (alpha_value * output.z);
output.w = output.w > 0 ? output.w : (alpha_value * output.w);
#endif
outTexture.write(VECTOR(P, 4)(output), gid.xy, gid.z);
}
kernel void FUNC3_(depthwise_conv_add_3x3, PRELU_TYPE, P)(texture2d_array<P, access::sample> inTexture [[texture(0)]],
texture2d_array<P, access::write> outTexture [[texture(1)]],
constant MetalConvParam &param [[buffer(0)]],
const device P *weights [[buffer(1)]],
const device VECTOR(P, 4) *biase [[buffer(2)]],
#ifdef PRELU_CHANNEL
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_ELEMENT
const device VECTOR(P, 4) *alpha [[buffer(3)]],
#endif
#ifdef PRELU_OTHER
const device P *alpha [[buffer(3)]],
#endif
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) {
return;
}
uint output_slice = gid.z;
ushort2 stride = ushort2(param.strideX, param.strideY);
ushort2 posInInput = ushort2(gid.xy) * stride + ushort2(param.offsetX, param.offsetY);
constexpr sampler sample(coord::pixel, filter::nearest, address::clamp_to_zero);
const uint kernelHXW = 9;
uint weithTo = gid.z * kernelHXW * 4;
float4 output = float4(biase[gid.z]);
VECTOR(P, 4) inputs[9];
inputs[0] = inTexture.sample(sample, float2(posInInput.x - 1, posInInput.y - 1), output_slice);
inputs[1] = inTexture.sample(sample, float2(posInInput.x, posInInput.y - 1), output_slice);
inputs[2] = inTexture.sample(sample, float2(posInInput.x + 1, posInInput.y - 1), output_slice);
inputs[3] = inTexture.sample(sample, float2(posInInput.x - 1, posInInput.y), output_slice);
inputs[4] = inTexture.sample(sample, float2(posInInput.x, posInInput.y), output_slice);
inputs[5] = inTexture.sample(sample, float2(posInInput.x + 1, posInInput.y), output_slice);
inputs[6] = inTexture.sample(sample, float2(posInInput.x - 1, posInInput.y + 1), output_slice);
inputs[7] = inTexture.sample(sample, float2(posInInput.x, posInInput.y + 1), output_slice);
inputs[8] = inTexture.sample(sample, float2(posInInput.x + 1, posInInput.y + 1), output_slice);
for (int j = 0; j < 9; ++j) {
VECTOR(P, 4) input = inputs[j];
output.x += input.x * weights[weithTo + 0 * kernelHXW + j];
output.y += input.y * weights[weithTo + 1 * kernelHXW + j];
output.z += input.z * weights[weithTo + 2 * kernelHXW + j];
output.w += input.w * weights[weithTo + 3 * kernelHXW + j];
}
#ifdef PRELU_CHANNEL
VECTOR(P, 4) alpha_value = alpha[gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_ELEMENT
int alpha_to = (gid.y * outTexture.get_width() + gid.x) * outTexture.get_array_size();
VECTOR(P, 4) alpha_value = alpha[alpha_to + gid.z];
output.x = output.x > 0 ? output.x : (alpha_value.x * output.x);
output.y = output.y > 0 ? output.y : (alpha_value.y * output.y);
output.z = output.z > 0 ? output.z : (alpha_value.z * output.z);
output.w = output.w > 0 ? output.w : (alpha_value.w * output.w);
#endif
#ifdef PRELU_OTHER
P alpha_value = alpha[0];
output.x = output.x > 0 ? output.x : (alpha_value * output.x);
output.y = output.y > 0 ? output.y : (alpha_value * output.y);
output.z = output.z > 0 ? output.z : (alpha_value * output.z);
output.w = output.w > 0 ? output.w : (alpha_value * output.w);
#endif
outTexture.write(VECTOR(P, 4)(output), gid.xy, gid.z);
}
#endif
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <metal_stdlib>
#include "Common.metal"
using namespace metal;
#define P float
#define PRELU_CHANNEL prelu_channel
#define PRELU_TYPE prelu_channel
#include "ConvAddPrelu.inc.metal"
#undef PRELU_TYPE
#undef PRELU_CHANNEL
#define PRELU_ELEMENT prelu_element
#define PRELU_TYPE prelu_element
#include "ConvAddPrelu.inc.metal"
#undef PRELU_TYPE
#undef PRELU_ELEMENT
#define PRELU_OTHER prelu_other
#define PRELU_TYPE prelu_other
#include "ConvAddPrelu.inc.metal"
#undef PRELU_TYPE
#undef PRELU_OTHER
#undef P
#define P half
#define PRELU_CHANNEL prelu_channel
#define PRELU_TYPE prelu_channel
#include "ConvAddPrelu.inc.metal"
#undef PRELU_TYPE
#undef PRELU_CHANNEL
#define PRELU_ELEMENT prelu_element
#define PRELU_TYPE prelu_element
#include "ConvAddPrelu.inc.metal"
#undef PRELU_TYPE
#undef PRELU_ELEMENT
#define PRELU_OTHER prelu_other
#define PRELU_TYPE prelu_other
#include "ConvAddPrelu.inc.metal"
#undef PRELU_TYPE
#undef PRELU_OTHER
#undef P
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <metal_stdlib>
using namespace metal;
kernel void fetch(texture2d_array<float, access::read> inTexture [[texture(0)]],
device float *output [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= inTexture.get_width() ||
gid.y >= inTexture.get_height() ||
gid.z >= inTexture.get_array_size()) {
return;
}
int input_width = inTexture.get_width();
int input_height = inTexture.get_height();
const float4 input = inTexture.read(gid.xy, gid.z);
int output_to = 4 * input_width * input_height;
output[gid.z * output_to + 0 * input_width * input_height + gid.y * input_width + gid.x] = input.x;
output[gid.z * output_to + 1 * input_width * input_height + gid.y * input_width + gid.x] = input.y;
output[gid.z * output_to + 2 * input_width * input_height + gid.y * input_width + gid.x] = input.z;
output[gid.z * output_to + 3 * input_width * input_height + gid.y * input_width + gid.x] = input.w;
}
kernel void fetch_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
device float * output [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= inTexture.get_width() ||
gid.y >= inTexture.get_height() ||
gid.z >= inTexture.get_array_size()) {
return;
}
int input_width = inTexture.get_width();
int input_height = inTexture.get_height();
const half4 input = inTexture.read(gid.xy, gid.z);
int output_to = 4 * input_width * input_height;
output[gid.z * output_to + 0 * input_width * input_height + gid.y * input_width + gid.x] = input.x;
output[gid.z * output_to + 1 * input_width * input_height + gid.y * input_width + gid.x] = input.y;
output[gid.z * output_to + 2 * input_width * input_height + gid.y * input_width + gid.x] = input.z;
output[gid.z * output_to + 3 * input_width * input_height + gid.y * input_width + gid.x] = input.w;
}
kernel void fetch_placeholder(texture2d_array<float, access::read> inTexture [[texture(0)]],
device float *output [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
}
kernel void fetch_placeholder_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
device float *output [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
}
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <metal_stdlib>
using namespace metal;
#define CONCAT2(a, b) a ## b
#define CONCAT2_(a, b) a ## _ ## b
#define CONCAT3_(a, b, c) a ## _ ## b ## _ ## c
#define CONCAT4_(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d
#define CONCAT5_(a, b, c, d, e) a ## _ ## b ## _ ## c ## _ ## d ## _ ## e
#define FUNC(f, r, n, v, p) CONCAT5_(f, r, n, v, p)
#define VECTOR(p, n) CONCAT2(p, n)
#define FUNC3_(a, b, c) CONCAT3_(a, b, c)
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <metal_stdlib>
using namespace metal;
kernel void nms_fetch_result(texture2d_array<float, access::read> inTexture [[texture(0)]],
device float *output [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= inTexture.get_width() ||
gid.y >= inTexture.get_height() ||
gid.z >= inTexture.get_array_size()) {
return;
}
int input_width = inTexture.get_width();
const float4 input = inTexture.read(gid.xy, gid.z);
output[gid.y * input_width + gid.x] = input.x;
}
kernel void nms_fetch_result_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
device float *output [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= inTexture.get_width() ||
gid.y >= inTexture.get_height() ||
gid.z >= inTexture.get_array_size()) {
return;
}
int input_width = inTexture.get_width();
const half4 input = inTexture.read(gid.xy, gid.z);
output[gid.y * input_width + gid.x] = input.x;
}
kernel void nms_fetch_bbox(texture2d_array<float, access::read> inTexture [[texture(0)]],
device float4 *output [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= inTexture.get_width() ||
gid.y >= inTexture.get_height() ||
gid.z >= inTexture.get_array_size()) {
return;
}
int input_width = inTexture.get_width();
// int input_height = inTexture.get_height();
const float4 input = inTexture.read(gid.xy, gid.z);
output[gid.y * input_width + gid.x] = input;
}
kernel void nms_fetch_bbox_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
device float4 *output [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= inTexture.get_width() ||
gid.y >= inTexture.get_height() ||
gid.z >= inTexture.get_array_size()) {
return;
}
int input_width = inTexture.get_width();
// int input_height = inTexture.get_height();
const half4 input = inTexture.read(gid.xy, gid.z);
output[gid.y * input_width + gid.x] = float4(input);
}
...@@ -161,3 +161,207 @@ kernel void prior_box_half(texture2d_array<half, access::read> inTexture [[textu ...@@ -161,3 +161,207 @@ kernel void prior_box_half(texture2d_array<half, access::read> inTexture [[textu
} }
} }
kernel void prior_box_MinMaxAspectRatiosOrder(texture2d_array<float, access::read> inTexture [[texture(0)]],
texture2d_array<float, access::write> outBoxTexture [[texture(1)]],
texture2d_array<float, access::write> varianceTexture [[texture(2)]],
const device float *aspect_ratios [[buffer(0)]],
constant PriorBoxMetalParam &param [[buffer(1)]],
const device float4 *variances [[buffer(2)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outBoxTexture.get_width() ||
gid.y >= outBoxTexture.get_height() ||
gid.z >= outBoxTexture.get_array_size()) return;
float center_x = (gid.x + param.offset) * param.stepWidth;
float center_y = (gid.y + param.offset) * param.stepHeight;
float box_width, box_height;
if (gid.z == 0) {
box_width = box_height = param.minSize / 2;
float4 box;
box.x = (center_x - box_width) / param.imageWidth;
box.y = (center_y - box_height) / param.imageHeight;
box.z = (center_x + box_width) / param.imageWidth;
box.w = (center_y + box_height) / param.imageHeight;
float4 res;
if (param.clip) {
res = fmin(fmax(box, 0.0), 1.0);
} else {
res = box;
}
outBoxTexture.write(res, gid.xy, gid.z);
}
if (gid.z == 1 && param.maxSizeSize > 0) {
box_width = box_height = sqrt(param.minSize * param.maxSize) / 2;
float4 max_box;
max_box.x = (center_x - box_width) / param.imageWidth;
max_box.y = (center_y - box_height) / param.imageHeight;
max_box.z = (center_x + box_width) / param.imageWidth;
max_box.w = (center_y + box_height) / param.imageHeight;
float4 res;
if (param.clip) {
res = min(max(max_box, 0.0), 1.0);
} else {
res = max_box;
}
outBoxTexture.write(res, gid.xy, gid.z);
}
int aspect_to = 0;
if (param.maxSizeSize > 0) {
aspect_to = gid.z - 2;
} else {
aspect_to = gid.z - 1;
}
if (aspect_to >= 0 && aspect_to < int(param.aspecRatiosSize)) {
int skip = 0;
for (int i = 0; i < aspect_to + 1; ++i) {
if (fabs(aspect_ratios[i] - 1.) < 1e-6) {
skip += 1;
}
}
aspect_to += skip;
float ar = aspect_ratios[aspect_to];
box_width = param.minSize * sqrt(ar) / 2;
box_height = param.minSize / sqrt(ar) / 2;
float4 box;
box.x = (center_x - box_width) / param.imageWidth;
box.y = (center_y - box_height) / param.imageHeight;
box.z = (center_x + box_width) / param.imageWidth;
box.w = (center_y + box_height) / param.imageHeight;
float4 res;
if (param.clip) {
res = fmin(fmax(box, 0.0), 1.0);
} else {
res = box;
}
outBoxTexture.write(res, gid.xy, gid.z);
}
float4 variance = variances[0];
if (gid.z < param.numPriors) {
float4 variances_output;
variances_output.x = variance.x;
variances_output.y = variance.y;
variances_output.z = variance.z;
variances_output.w = variance.w;
varianceTexture.write(variances_output, gid.xy, gid.z);
}
}
kernel void prior_box_MinMaxAspectRatiosOrder_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
texture2d_array<half, access::write> outBoxTexture [[texture(1)]],
texture2d_array<half, access::write> varianceTexture [[texture(2)]],
const device half *aspect_ratios [[buffer(0)]],
constant PriorBoxMetalParam &param [[buffer(1)]],
const device float4 *variances [[buffer(2)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outBoxTexture.get_width() ||
gid.y >= outBoxTexture.get_height() ||
gid.z >= outBoxTexture.get_array_size()) return;
float center_x = (gid.x + param.offset) * param.stepWidth;
float center_y = (gid.y + param.offset) * param.stepHeight;
float box_width, box_height;
if (gid.z == 0) {
box_width = box_height = param.minSize / 2;
float4 box;
box.x = (center_x - box_width) / param.imageWidth;
box.y = (center_y - box_height) / param.imageHeight;
box.z = (center_x + box_width) / param.imageWidth;
box.w = (center_y + box_height) / param.imageHeight;
float4 res;
if (param.clip) {
res = fmin(fmax(box, 0.0), 1.0);
} else {
res = box;
}
outBoxTexture.write(half4(res), gid.xy, gid.z);
}
if (gid.z == 1 && param.maxSizeSize > 0) {
box_width = box_height = sqrt(param.minSize * param.maxSize) / 2;
float4 max_box;
max_box.x = (center_x - box_width) / param.imageWidth;
max_box.y = (center_y - box_height) / param.imageHeight;
max_box.z = (center_x + box_width) / param.imageWidth;
max_box.w = (center_y + box_height) / param.imageHeight;
float4 res;
if (param.clip) {
res = min(max(max_box, 0.0), 1.0);
} else {
res = max_box;
}
outBoxTexture.write(half4(res), gid.xy, gid.z);
}
int aspect_to = 0;
if (param.maxSizeSize > 0) {
aspect_to = gid.z - 2;
} else {
aspect_to = gid.z - 1;
}
if (aspect_to > 0 && aspect_to < int(param.aspecRatiosSize) && fabs(aspect_ratios[aspect_to] - 1.) > 1e-6) {
float ar = aspect_ratios[aspect_to];
box_width = param.minSize * sqrt(ar) / 2;
box_height = param.minSize / sqrt(ar) / 2;
float4 box;
box.x = (center_x - box_width) / param.imageWidth;
box.y = (center_y - box_height) / param.imageHeight;
box.z = (center_x + box_width) / param.imageWidth;
box.w = (center_y + box_height) / param.imageHeight;
float4 res;
if (param.clip) {
res = fmin(fmax(box, 0.0), 1.0);
} else {
res = box;
}
outBoxTexture.write(half4(res), gid.xy, gid.z);
}
float4 variance = variances[0];
if (gid.z < param.numPriors) {
float4 variances_output;
variances_output.x = variance.x;
variances_output.y = variance.y;
variances_output.z = variance.z;
variances_output.w = variance.w;
varianceTexture.write(half4(variances_output), gid.xy, gid.z);
}
}
#ifdef P
#define CONCAT2(a, b) a ## b
#define CONCAT2_(a, b) a ## _ ## b
#define CONCAT3_(a, b, c) a ## _ ## b ## _ ## c
#define CONCAT4_(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d
#define FUNC(f, r1, r2, p) CONCAT4_(f, r1, r2, p)
#define VECTOR(p, n) CONCAT2(p, n)
#define FUNC_R(f, r) CONCAT2_(f, r)
kernel void FUNC(reshape, RIN, ROUT, P)(texture2d_array<P, access::read> inTexture [[texture(0)]],
texture2d_array<P, access::write> outTexture [[texture(1)]],
constant ReshapeParam &rp [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) return;
int oxyzn[4] = {int(gid.x), int(gid.y), int(gid.z), 0}, oabcd[4], ixyzn[4], iabcd[4];
ReshapeParam lrp = rp;
int oC = lrp.odim[lrp.otrans[3]];
int iC = lrp.idim[lrp.itrans[3]];
int count = lrp.odim[0] * lrp.odim[1] * lrp.odim[2] * lrp.odim[3];
VECTOR(P, 4) r;
for (int n = 0; n < 4; n++) {
oxyzn[3] = n;
#if ROUT == 4
xyzn2abcd_4(oC, oxyzn, oabcd);
#else
FUNC_R(xyzn2abcd, ROUT)(oxyzn, oabcd);
#endif
int tabcd[4];
invtrans(lrp.otrans, oabcd, tabcd);
int index = abcd2index(lrp.odim, tabcd);
if (index < count) {
index2abcd(lrp.idim, index, tabcd);
trans(lrp.itrans, tabcd, iabcd);
#if RIN == 4
abcd2xyzn_4(iC, iabcd, ixyzn);
#else
FUNC_R(abcd2xyzn, RIN)(iabcd, ixyzn);
#endif
r[n] = inTexture.read(uint2(ixyzn[0], ixyzn[1]), ixyzn[2])[ixyzn[3]];
} else {
r[n] = 0;
}
}
outTexture.write(r, gid.xy, gid.z);
}
#endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONRITIONS OF ANY KINR, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
...@@ -24,114 +24,127 @@ struct ReshapeParam { ...@@ -24,114 +24,127 @@ struct ReshapeParam {
int32_t otrans[4]; int32_t otrans[4];
}; };
//kernel void reshape(texture2d_array<float, access::read> inTexture [[texture(0)]], #define P float
// texture2d_array<float, access::write> outTexture [[texture(1)]], #define RIN 4
// constant ReshapeParam &rp [[buffer(0)]], #define ROUT 4
// uint3 gid [[thread_position_in_grid]]) { #include "ReshapeKernel.inc.metal"
// if (gid.x >= outTexture.get_width() || #undef ROUT
// gid.y >= outTexture.get_height() || #define ROUT 3
// gid.z >= outTexture.get_array_size()) return; #include "ReshapeKernel.inc.metal"
// #undef ROUT
// int oxyzn[4] = {int(gid.x), int(gid.y), int(gid.z), 0}, oabcd[4], ixyzn[4]; #define ROUT 2
// ReshapeParam lrp = rp; #include "ReshapeKernel.inc.metal"
// int oC = lrp.odim[lrp.otrans[3]]; #undef ROUT
// int iC = lrp.idim[lrp.itrans[3]]; #define ROUT 1
// int count = lrp.odim[0] * lrp.odim[1] * lrp.odim[2] * lrp.odim[3]; #include "ReshapeKernel.inc.metal"
// float4 r; #undef ROUT
// for (int n = 0; n < 4; n++) { #undef RIN
// oxyzn[3] = n;
// #define RIN 3
// //4 (gid.x gid.y, gid.z, 0~4) #define ROUT 4
// xyzn2abcd(oC, oxyzn, oabcd); #include "ReshapeKernel.inc.metal"
// int tabcd[4]; #undef ROUT
// invtrans(lrp.otrans, oabcd, tabcd); #define ROUT 3
// int index = abcd2index(lrp.odim, tabcd); #include "ReshapeKernel.inc.metal"
// if (index < count) { #undef ROUT
// int c = index % 4; #define ROUT 2
// #include "ReshapeKernel.inc.metal"
// int temp0 = index % (inTexture.get_array_size() * 4); #undef ROUT
// int slice = temp0 / 4; #define ROUT 1
// #include "ReshapeKernel.inc.metal"
// int temp1 = index % (inTexture.get_array_size() * 4 * lrp.idim[2]); #undef ROUT
// int w = temp1 / (inTexture.get_array_size() * 4); #undef RIN
//
// int h = index / (inTexture.get_array_size() * 4 * lrp.idim[2]); #define RIN 2
// #define ROUT 4
//// index2abcd(lrp.idim, index, tabcd); #include "ReshapeKernel.inc.metal"
//// abcd2xyzn(iC, tabcd, ixyzn); #undef ROUT
// r[n] = inTexture.read(uint2(w, h), slice)[c]; #define ROUT 3
// } else { #include "ReshapeKernel.inc.metal"
// r[n] = 0; #undef ROUT
// } #define ROUT 2
// } #include "ReshapeKernel.inc.metal"
// outTexture.write(r, gid.xy, gid.z); #undef ROUT
//} #define ROUT 1
#include "ReshapeKernel.inc.metal"
#undef ROUT
#undef RIN
kernel void reshape(texture2d_array<float, access::read> inTexture [[texture(0)]], #define RIN 1
texture2d_array<float, access::write> outTexture [[texture(1)]], #define ROUT 4
constant ReshapeParam &rp [[buffer(0)]], #include "ReshapeKernel.inc.metal"
uint3 gid [[thread_position_in_grid]]) { #undef ROUT
if (gid.x >= outTexture.get_width() || #define ROUT 3
gid.y >= outTexture.get_height() || #include "ReshapeKernel.inc.metal"
gid.z >= outTexture.get_array_size()) return; #undef ROUT
#define ROUT 2
int oxyzn[4] = {int(gid.x), int(gid.y), int(gid.z), 0}, oabcd[4], ixyzn[4], iabcd[4]; #include "ReshapeKernel.inc.metal"
ReshapeParam lrp = rp; #undef ROUT
int oC = lrp.odim[lrp.otrans[3]]; #define ROUT 1
int iC = lrp.idim[lrp.itrans[3]]; #include "ReshapeKernel.inc.metal"
int count = lrp.odim[0] * lrp.odim[1] * lrp.odim[2] * lrp.odim[3]; #undef ROUT
float4 r; #undef RIN
for (int n = 0; n < 4; n++) {
oxyzn[3] = n; #undef P
xyzn2abcd(oC, oxyzn, oabcd);
int tabcd[4]; #define P half
invtrans(lrp.otrans, oabcd, tabcd); #define RIN 4
int index = abcd2index(lrp.odim, tabcd); #define ROUT 4
if (index < count) { #include "ReshapeKernel.inc.metal"
index2abcd(lrp.idim, index, tabcd); #undef ROUT
trans(lrp.itrans, tabcd, iabcd); #define ROUT 3
abcd2xyzn(iC, iabcd, ixyzn); #include "ReshapeKernel.inc.metal"
r[n] = inTexture.read(uint2(ixyzn[0], ixyzn[1]), ixyzn[2])[ixyzn[3]]; #undef ROUT
} else { #define ROUT 2
r[n] = 0; #include "ReshapeKernel.inc.metal"
} #undef ROUT
} #define ROUT 1
outTexture.write(r, gid.xy, gid.z); #include "ReshapeKernel.inc.metal"
} #undef ROUT
#undef RIN
kernel void reshape_half(texture2d_array<half, access::read> inTexture [[texture(0)]], #define RIN 3
texture2d_array<half, access::write> outTexture [[texture(1)]], #define ROUT 4
constant ReshapeParam &rp [[buffer(0)]], #include "ReshapeKernel.inc.metal"
uint3 gid [[thread_position_in_grid]]) { #undef ROUT
if (gid.x >= outTexture.get_width() || #define ROUT 3
gid.y >= outTexture.get_height() || #include "ReshapeKernel.inc.metal"
gid.z >= outTexture.get_array_size()) return; #undef ROUT
#define ROUT 2
int oxyzn[4] = {int(gid.x), int(gid.y), int(gid.z), 0}, oabcd[4], ixyzn[4], iabcd[4]; #include "ReshapeKernel.inc.metal"
ReshapeParam lrp = rp; #undef ROUT
int oC = lrp.odim[lrp.otrans[3]]; #define ROUT 1
int iC = lrp.idim[lrp.itrans[3]]; #include "ReshapeKernel.inc.metal"
int count = lrp.odim[0] * lrp.odim[1] * lrp.odim[2] * lrp.odim[3]; #undef ROUT
half4 r; #undef RIN
for (int n = 0; n < 4; n++) {
oxyzn[3] = n; #define RIN 2
xyzn2abcd(oC, oxyzn, oabcd); #define ROUT 4
int tabcd[4]; #include "ReshapeKernel.inc.metal"
invtrans(lrp.otrans, oabcd, tabcd); #undef ROUT
int index = abcd2index(lrp.odim, tabcd); #define ROUT 3
if (index < count) { #include "ReshapeKernel.inc.metal"
index2abcd(lrp.idim, index, tabcd); #undef ROUT
trans(lrp.itrans, tabcd, iabcd); #define ROUT 2
abcd2xyzn(iC, iabcd, ixyzn); #include "ReshapeKernel.inc.metal"
r[n] = inTexture.read(uint2(ixyzn[0], ixyzn[1]), ixyzn[2])[ixyzn[3]]; #undef ROUT
} else { #define ROUT 1
r[n] = 0; #include "ReshapeKernel.inc.metal"
} #undef ROUT
} #undef RIN
outTexture.write(r, gid.xy, gid.z);
} #define RIN 1
#define ROUT 4
#include "ReshapeKernel.inc.metal"
#undef ROUT
#define ROUT 3
#include "ReshapeKernel.inc.metal"
#undef ROUT
#define ROUT 2
#include "ReshapeKernel.inc.metal"
#undef ROUT
#define ROUT 1
#include "ReshapeKernel.inc.metal"
#undef ROUT
#undef RIN
#undef P
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <metal_stdlib>
using namespace metal;
kernel void shape() {
}
kernel void shape_half() {
}
#ifdef P
#define CONCAT2(a, b) a ## b
#define CONCAT2_(a, b) a ## _ ## b
#define FUNC(f, p) CONCAT2_(f, p)
#define VECTOR(p, n) CONCAT2(p, n)
kernel void FUNC(softmax, P)(texture2d_array<P, access::read> inTexture [[texture(0)]],
texture2d_array<P, access::write> outTexture [[texture(1)]],
constant SoftmaxParam &sp [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) return;
// int zsize = inTexture.get_array_size();
P maxv = inTexture.read(uint2(0, gid.y), 0)[0];
int group = sp.K / 4;
int remain = sp.K % 4;
for (int x = 0; x < group; x++) {
VECTOR(P, 4) r = inTexture.read(uint2(x, gid.y), 0);
maxv = max(maxv, max(r[0], max(r[1], max(r[2], r[3]))));
}
if (remain > 0) {
VECTOR(P, 4) r = inTexture.read(uint2(group, gid.y), 0);
for (int i = 0; i < remain; i++) {
maxv = max(maxv, r[i]);
}
}
VECTOR(P, 4) rsum = {0, 0, 0, 0};
for (int x = 0; x < group; x++) {
VECTOR(P, 4) r = inTexture.read(uint2(x, gid.y), 0);
rsum += exp(r - maxv);
}
P sum = rsum[0] + rsum[1] + rsum[2] + rsum[3];
if (remain > 0) {
VECTOR(P, 4) r = inTexture.read(uint2(group, gid.y), 0);
for (int i = 0; i < remain; i++) {
sum += exp(r[i] - maxv);
}
}
VECTOR(P, 4) rr = inTexture.read(gid.xy, gid.z);
rr = exp(rr - maxv) / sum;
outTexture.write(rr, gid.xy, gid.z);
}
#endif
...@@ -20,81 +20,10 @@ struct SoftmaxParam { ...@@ -20,81 +20,10 @@ struct SoftmaxParam {
int K; int K;
}; };
kernel void softmax(texture2d_array<float, access::read> inTexture [[texture(0)]], #define P float
texture2d_array<float, access::write> outTexture [[texture(1)]], #include "Softmax.inc.metal"
constant SoftmaxParam &sp [[buffer(0)]], #undef P
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) return;
// int zsize = inTexture.get_array_size();
float maxv = inTexture.read(gid.xy, 0)[0];
int group = sp.K / 4;
int remain = sp.K % 4;
for (int z = 0; z < group; z++) {
float4 r = inTexture.read(gid.xy, z);
maxv = max(maxv, max(r[0], max(r[1], max(r[2], r[3]))));
}
if (remain > 0) {
float4 r = inTexture.read(gid.xy, group);
for (int i = 0; i < remain; i++) {
maxv = max(maxv, r[i]);
}
}
float4 rsum = {0, 0, 0, 0};
for (int z = 0; z < group; z++) {
float4 r = inTexture.read(gid.xy, z);
rsum += exp(r - maxv);
}
float sum = rsum[0] + rsum[1] + rsum[2] + rsum[3];
if (remain > 0) {
float4 r = inTexture.read(gid.xy, group);
for (int i = 0; i < remain; i++) {
sum += exp(r[i] - maxv);
}
}
float4 rr = inTexture.read(gid.xy, gid.z);
rr = exp(rr - maxv) / sum;
outTexture.write(rr, gid.xy, gid.z);
}
kernel void softmax_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
texture2d_array<half, access::write> outTexture [[texture(1)]],
constant SoftmaxParam &sp [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
if (gid.x >= outTexture.get_width() ||
gid.y >= outTexture.get_height() ||
gid.z >= outTexture.get_array_size()) return;
// int zsize = inTexture.get_array_size();
half maxv = inTexture.read(gid.xy, 0)[0];
int group = sp.K / 4;
int remain = sp.K % 4;
for (int z = 0; z < group; z++) {
half4 r = inTexture.read(gid.xy, z);
maxv = max(maxv, max(r[0], max(r[1], max(r[2], r[3]))));
}
if (remain > 0) {
half4 r = inTexture.read(gid.xy, group);
for (int i = 0; i < remain; i++) {
maxv = max(maxv, r[i]);
}
}
float4 rsum = {0, 0, 0, 0};
for (int z = 0; z < group; z++) {
half4 r = inTexture.read(gid.xy, z);
rsum += exp(float4(r) - float4(maxv));
}
float sum = rsum[0] + rsum[1] + rsum[2] + rsum[3];
if (remain > 0) {
half4 r = inTexture.read(gid.xy, group);
for (int i = 0; i < remain; i++) {
sum += exp(float(r[i]) - float(maxv));
}
}
half4 rr = inTexture.read(gid.xy, gid.z);
rr = half4(exp(float4(rr) - float(maxv)) / sum);
outTexture.write(rr, gid.xy, gid.z);
}
#define P half
#include "Softmax.inc.metal"
#undef P
#ifdef P
#define CONCAT2(a, b) a ## b
#define CONCAT2_(a, b) a ## _ ## b
#define CONCAT3_(a, b, c) a ## _ ## b ## _ ## c
#define CONCAT4_(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d
#define CONCAT5_(a, b, c, d, e) a ## _ ## b ## _ ## c ## _ ## d ## _ ## e
#define FUNC(f, r, n, v, p) CONCAT5_(f, r, n, v, p)
#define VECTOR(p, n) CONCAT2(p, n)
#define FUNC_R(f, r) CONCAT2_(f, r)
#if V == VX
#define VV x
#elif V == VY
#define VV y
#elif V == VZ
#define VV z
#else
#define VV normal
#endif
#if V == VY
kernel void FUNC(split, R, N, VV, P)(texture2d_array<P, access::read> input [[texture(0)]],
texture2d_array<P, access::write> out1 [[texture(1)]],
texture2d_array<P, access::write> out2 [[texture(2)]],
#if N >= 3
texture2d_array<P, access::write> out3 [[texture(3)]],
#endif // N >= 3
#if N >= 4
texture2d_array<P, access::write> out4 [[texture(4)]],
#endif // N >= 4
constant SplitParam &sp [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
VECTOR(P, 4) r = input.read(gid.xy, gid.z);
int y = gid.y - sp.offset;
if (y < sp.vdim[0]) {
out1.write(r, gid.xy, gid.z);
return;
}
y -= sp.vdim[0];
if (y < sp.vdim[1]) {
out2.write(r, uint2(gid.x, y), gid.z);
return;
}
#if N >= 3
y -= sp.vdim[1];
if (y < sp.vdim[2]) {
out3.write(r, uint2(gid.x, y), gid.z);
return;
}
#endif // N >= 3
#if N >= 4
y -= sp.vdim[2];
if (y < sp.vdim[3]) {
out4.write(r, uint2(gid.x, y), gid.z);
return;
}
#endif // N >= 4
}
#endif // V == VY
#if V == VX
kernel void FUNC(split, R, N, VV, P)(texture2d_array<P, access::read> input [[texture(0)]],
texture2d_array<P, access::write> out1 [[texture(1)]],
texture2d_array<P, access::write> out2 [[texture(2)]],
#if N >= 3
texture2d_array<P, access::write> out3 [[texture(3)]],
#endif // N >= 3
#if N >= 4
texture2d_array<P, access::write> out4 [[texture(4)]],
#endif // N >= 4
constant SplitParam &sp [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
VECTOR(P, 4) r = input.read(gid.xy, gid.z);
int x = gid.x;
if (x < sp.vdim[0]) {
out1.write(r, gid.xy, gid.z);
return;
}
x -= sp.vdim[0];
if (x < sp.vdim[1]) {
out2.write(r, uint2(x, gid.y), gid.z);
return;
}
#if N >= 3
x -= sp.vdim[1];
if (x < sp.vdim[2]) {
out3.write(r, uint2(x, gid.y), gid.z);
return;
}
#endif // N >= 3
#if N >= 4
x -= sp.vdim[2];
if (x < sp.vdim[3]) {
out4.write(r, uint2(x, gid.y), gid.z);
return;
}
#endif // N >= 4
}
#endif // V == VX
#undef VV
#endif
...@@ -13,18 +13,52 @@ ...@@ -13,18 +13,52 @@
limitations under the License. */ limitations under the License. */
#include <metal_stdlib> #include <metal_stdlib>
#include "Common.metal"
using namespace metal; using namespace metal;
kernel void split(texture2d_array<float, access::write> output[[texture(0)]], struct SplitParam {
uint3 gid [[thread_position_in_grid]]) { int32_t idim[4];
float4 r; int32_t axis;
int32_t offset;
int32_t trans[4];
int32_t vdim[4];
};
#define VNORMAL 1
#define VX 2
#define VY 3
#define VZ 4
// only support split_{2, 3, 4}_{2, 3, 4}_y_{float, half}
// only support split_{3, 4}_{2, 3, 4}_x_{float, half}
output.write(r, gid.xy, gid.z); //// ssd-ar: (R=3, N=2, V=y)
} #define V VY
#define R 3
#define N 2
#define P float
#include "Split.inc.metal"
#undef P
#define P half
#include "Split.inc.metal"
#undef P
#undef N
#undef R
#undef V
kernel void split_half(texture2d_array<half, access::write> output[[texture(0)]],
uint3 gid [[thread_position_in_grid]]) {
float4 r;
output.write(half4(r), gid.xy, gid.z); //// ssd-ar: (R=2, N=2, V=y)
} #define V VY
#define R 2
#define N 2
#define P float
#include "Split.inc.metal"
#undef P
#define P half
#include "Split.inc.metal"
#undef P
#undef N
#undef R
#undef V
#ifdef P
#define CONCAT2(a, b) a ## b
#define CONCAT2_(a, b) a ## _ ## b
#define CONCAT3_(a, b, c) a ## _ ## b ## _ ## c
#define FUNC(f, r, p) CONCAT3_(f, r, p)
#define VECTOR(p, n) CONCAT2(p, n)
kernel void FUNC(transpose, R, P)(texture2d_array<P, access::read> inTexture [[texture(0)]],
texture2d_array<P, access::write> outTexture [[texture(1)]],
constant TransposeParam &pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) {
VECTOR(P, 4) r;
int oxyzn[4] = {int(gid.x), int(gid.y), int(gid.z), 0};
int iabcd[4], oabcd[4], ixyzn[4];
for (int n = 0; n < 4; n++) {
oxyzn[3] = n;
#if R == 4
xyzn2abcd_4(pm.oC, oxyzn, iabcd);
#endif // R == 4
#if R == 3
xyzn2abcd_3(oxyzn, oabcd);
#endif // R == 3
#if R == 2
xyzn2abcd_2(oxyzn, oabcd);
#endif // R == 2
iabcd[pm.axis[0]] = oabcd[0];
iabcd[pm.axis[1]] = oabcd[1];
iabcd[pm.axis[2]] = oabcd[2];
iabcd[pm.axis[3]] = oabcd[3];
#if R == 4
abcd2xyzn_4(pm.iC, iabcd, ixyzn);
#endif // R == 4
#if R == 3
abcd2xyzn_3(iabcd, ixyzn);
#endif // R == 3
#if R == 2
abcd2xyzn_2(iabcd, ixyzn);
#endif // R == 2
r[n] = inTexture.read(uint2(ixyzn[0], ixyzn[1]), ixyzn[2])[ixyzn[3]];
}
outTexture.write(r, gid.xy, gid.z);
}
#endif
...@@ -22,59 +22,42 @@ struct TransposeParam { ...@@ -22,59 +22,42 @@ struct TransposeParam {
int axis[4]; int axis[4];
}; };
kernel void transpose(texture2d_array<float, access::read> inTexture [[texture(0)]], kernel void transpose_copy_float(texture2d_array<float, access::read> inTexture [[texture(0)]],
texture2d_array<float, access::write> outTexture [[texture(1)]], texture2d_array<float, access::write> outTexture [[texture(1)]],
constant TransposeParam &pm [[buffer(0)]], constant TransposeParam &pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) { uint3 gid [[thread_position_in_grid]]) {
outTexture.write(inTexture.read(gid.xy, gid.z), gid.xy, gid.z);
if ((pm.axis[0] == 0) && (pm.axis[1] == 1) && (pm.axis[2] == 2) && (pm.axis[3] == 3)) {
// do nothing
float4 r = inTexture.read(gid.xy, gid.z);
outTexture.write(r, gid.xy, gid.z);
} else {
float4 r;
for (int n = 0; n < 4; n++) {
int ixyzn[] = {int(gid.x), int(gid.y), int(gid.z), n};
int iabcd[4], oabcd[4], oxyzn[4];
xyzn2abcd(pm.oC, ixyzn, iabcd);
oabcd[pm.axis[0]] = iabcd[0];
oabcd[pm.axis[1]] = iabcd[1];
oabcd[pm.axis[2]] = iabcd[2];
oabcd[pm.axis[3]] = iabcd[3];
abcd2xyzn(pm.iC, oabcd, oxyzn);
float4 rt = inTexture.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2]);
r[n] = rt[oxyzn[3]];
}
outTexture.write(r, gid.xy, gid.z);
}
} }
kernel void transpose_copy_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
kernel void transpose_half(texture2d_array<half, access::read> inTexture [[texture(0)]],
texture2d_array<half, access::write> outTexture [[texture(1)]], texture2d_array<half, access::write> outTexture [[texture(1)]],
constant TransposeParam &pm [[buffer(0)]], constant TransposeParam &pm [[buffer(0)]],
uint3 gid [[thread_position_in_grid]]) { uint3 gid [[thread_position_in_grid]]) {
outTexture.write(inTexture.read(gid.xy, gid.z), gid.xy, gid.z);
if ((pm.axis[0] == 0) && (pm.axis[1] == 1) && (pm.axis[2] == 2) && (pm.axis[3] == 3)) {
// do nothing
half4 r = inTexture.read(gid.xy, gid.z);
outTexture.write(r, gid.xy, gid.z);
} else {
half4 r;
for (int n = 0; n < 4; n++) {
int ixyzn[] = {int(gid.x), int(gid.y), int(gid.z), n};
int iabcd[4], oabcd[4], oxyzn[4];
xyzn2abcd(pm.oC, ixyzn, iabcd);
oabcd[pm.axis[0]] = iabcd[0];
oabcd[pm.axis[1]] = iabcd[1];
oabcd[pm.axis[2]] = iabcd[2];
oabcd[pm.axis[3]] = iabcd[3];
abcd2xyzn(pm.iC, oabcd, oxyzn);
half4 rt = inTexture.read(uint2(oxyzn[0], oxyzn[1]), oxyzn[2]);
r[n] = rt[oxyzn[3]];
}
outTexture.write(r, gid.xy, gid.z);
}
} }
#define R 4
#define P float
#include "TransposeKernel.inc.metal"
#undef P
#define P half
#include "TransposeKernel.inc.metal"
#undef P
#undef R
#define R 3
#define P float
#include "TransposeKernel.inc.metal"
#undef P
#define P half
#include "TransposeKernel.inc.metal"
#undef P
#undef R
#define R 2
#define P float
#include "TransposeKernel.inc.metal"
#undef P
#define P half
#include "TransposeKernel.inc.metal"
#undef P
#undef R
...@@ -21,10 +21,16 @@ class MulticlassNMSParam<P: PrecisionType>: OpParam { ...@@ -21,10 +21,16 @@ class MulticlassNMSParam<P: PrecisionType>: OpParam {
scores = try MulticlassNMSParam.getFirstTensor(key: "Scores", map: opDesc.inputs, from: inScope) scores = try MulticlassNMSParam.getFirstTensor(key: "Scores", map: opDesc.inputs, from: inScope)
bboxes = try MulticlassNMSParam.getFirstTensor(key: "BBoxes", map: opDesc.inputs, from: inScope) bboxes = try MulticlassNMSParam.getFirstTensor(key: "BBoxes", map: opDesc.inputs, from: inScope)
output = try MulticlassNMSParam.outputOut(outputs: opDesc.outputs, from: inScope) output = try MulticlassNMSParam.outputOut(outputs: opDesc.outputs, from: inScope)
middleOutput = FetchHolder.init(inCapacity: scores.tensorDim.numel(), inDim: scores.tensorDim.dims)
bboxOutput = FetchHolder.init(inCapacity: bboxes.tensorDim.numel(), inDim: bboxes.tensorDim.dims)
} catch let error { } catch let error {
throw error throw error
} }
} }
var bboxOutput: FetchHolder
var middleOutput: FetchHolder
let scores: Texture<P> let scores: Texture<P>
let bboxes: Texture<P> let bboxes: Texture<P>
var output: Texture<P> var output: Texture<P>
...@@ -33,7 +39,15 @@ class MulticlassNMSParam<P: PrecisionType>: OpParam { ...@@ -33,7 +39,15 @@ class MulticlassNMSParam<P: PrecisionType>: OpParam {
class MulticlassNMSOp<P: PrecisionType>: Operator<MulticlassNMSKernel<P>, MulticlassNMSParam<P>>, Runable, Creator, InferShaperable{ class MulticlassNMSOp<P: PrecisionType>: Operator<MulticlassNMSKernel<P>, MulticlassNMSParam<P>>, Runable, Creator, InferShaperable{
func inputVariant() -> [String : [Variant]] { func inputVariant() -> [String : [Variant]] {
return ["Scores" : [para.scores], "BBoxes" : [para.bboxes]] return ["Scores" : [para.middleOutput], "BBoxes" : [para.bboxOutput]]
}
func computeMiddleResult(device: MTLDevice, buffer: MTLCommandBuffer) {
do {
try kernel.compute(commandBuffer: buffer, param: para)
} catch let _ {
fatalError()
}
} }
func inferShape() { func inferShape() {
...@@ -42,11 +56,12 @@ class MulticlassNMSOp<P: PrecisionType>: Operator<MulticlassNMSKernel<P>, Multic ...@@ -42,11 +56,12 @@ class MulticlassNMSOp<P: PrecisionType>: Operator<MulticlassNMSKernel<P>, Multic
typealias OpType = MulticlassNMSOp<P> typealias OpType = MulticlassNMSOp<P>
func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws { func runImpl(device: MTLDevice, buffer: MTLCommandBuffer) throws {
do {
try kernel.compute(commandBuffer: buffer, param: para)
} catch let error {
throw error
} }
func delogOutput() {
print(" nms - output: ")
print(para.bboxes.metalTexture.float32Array().strideArray())
} }
} }
......
...@@ -17,6 +17,11 @@ import Foundation ...@@ -17,6 +17,11 @@ import Foundation
class PriorBoxParam<P: PrecisionType>: OpParam { class PriorBoxParam<P: PrecisionType>: OpParam {
typealias ParamPrecisionType = P typealias ParamPrecisionType = P
required init(opDesc: OpDesc, inScope: Scope) throws { required init(opDesc: OpDesc, inScope: Scope) throws {
do {
min_max_aspect_ratios_order = try PriorBoxParam.getAttr(key: "min_max_aspect_ratios_order", attrs: opDesc.attrs)
} catch _ {
}
do { do {
input = try PriorBoxParam.input(inputs: opDesc.inputs, from: inScope) input = try PriorBoxParam.input(inputs: opDesc.inputs, from: inScope)
output = try PriorBoxParam.outputBoxes(outputs: opDesc.outputs, from: inScope) output = try PriorBoxParam.outputBoxes(outputs: opDesc.outputs, from: inScope)
...@@ -36,6 +41,7 @@ class PriorBoxParam<P: PrecisionType>: OpParam { ...@@ -36,6 +41,7 @@ class PriorBoxParam<P: PrecisionType>: OpParam {
} }
} }
var min_max_aspect_ratios_order: Bool = false
let minSizes: [Float32] let minSizes: [Float32]
let maxSizes: [Float32] let maxSizes: [Float32]
let aspectRatios: [Float32] let aspectRatios: [Float32]
...@@ -72,10 +78,24 @@ class PriorBoxOp<P: PrecisionType>: Operator<PriorBoxKernel<P>, PriorBoxParam<P> ...@@ -72,10 +78,24 @@ class PriorBoxOp<P: PrecisionType>: Operator<PriorBoxKernel<P>, PriorBoxParam<P>
print(" \(type) output: ") print(" \(type) output: ")
// output // output
let outputArray = para.output.metalTexture.float32Array() // let outputArray = para.output.metalTexture.float32Array()
print(outputArray) // print(outputArray.strideArray())
// let device = para.input.metalTexture!.device
// let boxes:[Float32] = device.texture2tensor(texture: para.output.metalTexture!, dim: para.output.tensorDim.dims, transpose: [2,0,1,3])
// let variances:[Float32] = device.texture2tensor(texture: para.outputVariances.metalTexture!, dim: para.outputVariances.tensorDim.dims, transpose: [2,0,1,3])
// print("boxes: ")
// print(boxes.strideArray())
// print("variances: ")
// print(variances.strideArray())
// output // output
// print(" \(type) output: ") print(" \(type) output: ")
let box = para.output.metalTexture.realNHWC(dim: (para.output.dim[0], para.output.dim[1], para.output.dim[2], para.output.dim[3]))
print(" dim: \(para.output.dim)")
print(box.strideArray())
// print((0..<box.count).map { (index: $0, value: box[$0])})
// print(para.output.realNHWC().strideArray())
// let padToFourDim = para.output.padToFourDim // let padToFourDim = para.output.padToFourDim
// if para.output.transpose == [0, 1, 2, 3] { // if para.output.transpose == [0, 1, 2, 3] {
// let outputArray: [Float32] = para.output.metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3]), texturePrecision: computePrecision) // let outputArray: [Float32] = para.output.metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3]), texturePrecision: computePrecision)
......
...@@ -47,6 +47,9 @@ class ReluOp<P: PrecisionType>: Operator<ReluKernel<P>, ReluParam<P>>, Runable, ...@@ -47,6 +47,9 @@ class ReluOp<P: PrecisionType>: Operator<ReluKernel<P>, ReluParam<P>>, Runable,
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()) print(para.output.metalTexture.toTensor(dim: (n: para.output.tensorDim[0], c: para.output.tensorDim[1], h: para.output.tensorDim[2], w: para.output.tensorDim[3])).strideArray())
let device = para.output.metalTexture!.device
let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
print(outputArray.strideArray())
} }
} }
......
...@@ -43,15 +43,12 @@ class ReshapeParam<P: PrecisionType>: OpParam { ...@@ -43,15 +43,12 @@ class ReshapeParam<P: PrecisionType>: OpParam {
} }
output.padToFourDim = Dim.init(inDim: dim) output.padToFourDim = Dim.init(inDim: dim)
output.dim = output.padToFourDim output.dim = output.padToFourDim
// inplace = try ReshapeParam.getAttr(key: "inplace", attrs: opDesc.attrs)
} catch let error { } catch let error {
throw error throw error
} }
} }
let input: Texture<P> let input: Texture<P>
let shape: [Int32] let shape: [Int32]
// let inplace: Bool
var output: Texture<P> var output: Texture<P>
} }
...@@ -72,15 +69,9 @@ class ReshapeOp<P: PrecisionType>: Operator<ReshapeKernel<P>, ReshapeParam<P>>, ...@@ -72,15 +69,9 @@ class ReshapeOp<P: PrecisionType>: Operator<ReshapeKernel<P>, ReshapeParam<P>>,
} }
func delogOutput() { func delogOutput() {
print("reshape delog") print("reshape delog")
// let _: P? = para.input.metalTexture.logDesc(header: "reshape input: ", stridable: false) let device = para.output.metalTexture!.device
// let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
// let _: P? = para.output.metalTexture.logDesc(header: "reshape output: ", stridable: false)
let padToFourDim = para.output.padToFourDim
let outputArray: [Float32] = para.output.metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3]))
// print(para.output.metalTexture.toTensor(dim: (n: padToFourDim[0], c: padToFourDim[1], h: padToFourDim[2], w: padToFourDim[3])).strideArray())
print(outputArray.strideArray()) print(outputArray.strideArray())
// print(outputArray)
} }
} }
...@@ -18,17 +18,19 @@ class ShapeParam<P: PrecisionType>: OpParam { ...@@ -18,17 +18,19 @@ class ShapeParam<P: PrecisionType>: OpParam {
typealias ParamPrecisionType = P typealias ParamPrecisionType = P
required init(opDesc: OpDesc, inScope: Scope) throws { required init(opDesc: OpDesc, inScope: Scope) throws {
do { do {
output = try ShapeParam.output(outputs: opDesc.outputs, from: inScope) input = try ShapeParam.input(inputs: opDesc.inputs, from: inScope)
output = try ShapeParam.outputOut(outputs: opDesc.outputs, from: inScope)
} catch let error { } catch let error {
throw error throw error
} }
} }
var output: Texture<P> var output: Texture<P>
let input: Texture<P>
} }
class ShapeOp<P: PrecisionType>: Operator<SplitKernel<P>, SplitParam<P>>, Runable, Creator, InferShaperable{ class ShapeOp<P: PrecisionType>: Operator<ShapeKernel<P>, ShapeParam<P>>, Runable, Creator, InferShaperable{
typealias OpType = SplitOp<P> typealias OpType = ShapeOp<P>
func inferShape() { func inferShape() {
// para.output.dim = para.input.dim // para.output.dim = para.input.dim
......
...@@ -18,13 +18,33 @@ class SplitParam<P: PrecisionType>: OpParam { ...@@ -18,13 +18,33 @@ class SplitParam<P: PrecisionType>: OpParam {
typealias ParamPrecisionType = P typealias ParamPrecisionType = P
required init(opDesc: OpDesc, inScope: Scope) throws { required init(opDesc: OpDesc, inScope: Scope) throws {
do { do {
// output = try SplitParam.output(outputs: opDesc.outputs, from: inScope) input = try SplitParam.inputX(inputs: opDesc.inputs, from: inScope)
output = try SplitParam.outputOut(outputs: opDesc.outputs, from: inScope) output = Texture<P>.init(device: input.metalTexture!.device, inDim: input.dim)
axis = try SplitParam.getAttr(key: "axis", attrs: opDesc.attrs)
sections = try SplitParam.getAttr(key: "sections", attrs: opDesc.attrs)
if axis < 0 {
axis = input.tensorDim.cout() + axis
}
guard let outlist = opDesc.outputs["Out"] else {
fatalError()
}
for out in outlist {
guard let variant = inScope[out], let v = variant as? Texture<P> else {
fatalError()
}
outputList.append(v)
sections.append(Int32(v.tensorDim.dims[axis]))
}
} catch let error { } catch let error {
throw error throw error
} }
} }
var axis: Int
let input: Texture<P>
var output: Texture<P> var output: Texture<P>
var outputList: [Texture<P>] = []
var sections: [Int32] = []
} }
class SplitOp<P: PrecisionType>: Operator<SplitKernel<P>, SplitParam<P>>, Runable, Creator, InferShaperable{ class SplitOp<P: PrecisionType>: Operator<SplitKernel<P>, SplitParam<P>>, Runable, Creator, InferShaperable{
...@@ -45,6 +65,11 @@ class SplitOp<P: PrecisionType>: Operator<SplitKernel<P>, SplitParam<P>>, Runabl ...@@ -45,6 +65,11 @@ class SplitOp<P: PrecisionType>: Operator<SplitKernel<P>, SplitParam<P>>, Runabl
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
let device = para.input.metalTexture!.device
for out in para.outputList {
let arr: [Float32] = device.texture2tensor(texture: out.metalTexture, dim: out.tensorDim.dims, transpose: out.transpose)
print(arr.strideArray())
}
} }
} }
......
...@@ -48,15 +48,9 @@ class TransposeOp<P: PrecisionType>: Operator<TransposeKernel<P>, TransposeParam ...@@ -48,15 +48,9 @@ class TransposeOp<P: PrecisionType>: Operator<TransposeKernel<P>, TransposeParam
func delogOutput() { func delogOutput() {
print(" \(type) output: ") print(" \(type) output: ")
let padToFourDim = para.output.padToFourDim let device = para.output.metalTexture!.device
if para.output.transpose == [0, 1, 2, 3] { let outputArray: [Float32] = device.texture2tensor(texture: para.output.metalTexture, dim: para.output.tensorDim.dims, transpose: para.output.transpose)
let outputArray = para.output.metalTexture.realNHWC(dim: (n: padToFourDim[0], h: padToFourDim[1], w: padToFourDim[2], c: padToFourDim[3]))
print(outputArray.strideArray()) print(outputArray.strideArray())
} else if para.output.transpose == [0, 2, 3, 1] {
print(para.output.metalTexture.toTensor(dim: (n: para.output.tensorDim[0], c: para.output.tensorDim[1], h: para.output.tensorDim[2], w: para.output.tensorDim[3])).strideArray())
} else {
print(" not implement")
}
} }
} }
......
...@@ -16,40 +16,15 @@ import Foundation ...@@ -16,40 +16,15 @@ import Foundation
class ScaleKernel: CusomKernel { class ScaleKernel: CusomKernel {
init(device: MTLDevice, shape: Shape) { init(device: MTLDevice, shape: Shape) {
if computePrecision == .Float32 {
super.init(device: device, inFunctionName: "scale", outputDim: shape, usePaddleMobileLib: false)
} else if computePrecision == .Float16 {
super.init(device: device, inFunctionName: "scale_half", outputDim: shape, usePaddleMobileLib: false) super.init(device: device, inFunctionName: "scale_half", outputDim: shape, usePaddleMobileLib: false)
} else {
fatalError(" unsupport ")
} }
}
public class Net: NSObject {
var except: Int = 0
var means: [Float] = []
var scale: Float = 0.0
var dim: (n: Int, h: Int, w: Int, c: Int) = (n: 0, h: 0, w: 0, c: 0)
var preprocessKernel: CusomKernel? = nil
var paramPointer: UnsafeMutableRawPointer? = nil
var paramSize: Int = 0
var modelPointer: UnsafeMutableRawPointer? = nil
var modelSize: Int = 0
var modelPath: String = ""
var paramPath: String = ""
var modelDir: String = ""
public func resultStr(res: [Float]) -> String {
fatalError()
}
func fetchResult(paddleMobileRes: ResultHolder) -> [Float32] {
return paddleMobileRes.resultArr
}
@objc public init(device: MTLDevice) {
super.init()
} }
@objc public init(device: MTLDevice,paramPointer: UnsafeMutableRawPointer, paramSize:Int, modePointer: UnsafeMutableRawPointer, modelSize: Int) {
self.paramPointer = paramPointer
self.paramSize = paramSize
self.modelPointer = modePointer
self.modelSize = modelSize
super.init()
}
} }
public class Runner: NSObject { public class Runner: NSObject {
...@@ -60,7 +35,7 @@ public class Runner: NSObject { ...@@ -60,7 +35,7 @@ public class Runner: NSObject {
public let net: Net public let net: Net
let device: MTLDevice? let device: MTLDevice?
let platform: Platform let platform: Platform
var cpuPaddleMobile: PaddleMobile? var cpuPaddleMobile: PaddleMobileCPU?
let numel: Int let numel: Int
let meansNumber: [NSNumber] let meansNumber: [NSNumber]
...@@ -80,7 +55,7 @@ public class Runner: NSObject { ...@@ -80,7 +55,7 @@ public class Runner: NSObject {
textureLoader = MTKTextureLoader.init(device: inDevice) textureLoader = MTKTextureLoader.init(device: inDevice)
} }
if platform == .CPU { if platform == .CPU {
cpuPaddleMobile = PaddleMobile.init() cpuPaddleMobile = PaddleMobileCPU.init()
} }
numel = net.dim.n * net.dim.c * net.dim.h * net.dim.w numel = net.dim.n * net.dim.c * net.dim.h * net.dim.w
meansNumber = net.means.map { NSNumber.init(value: $0) } meansNumber = net.means.map { NSNumber.init(value: $0) }
...@@ -101,8 +76,10 @@ public class Runner: NSObject { ...@@ -101,8 +76,10 @@ public class Runner: NSObject {
} }
let loader = Loader<Float32>.init() let loader = Loader<Float32>.init()
do { do {
//program = try loader.load(device: inDevice, modelPath: net.modelPath, paraPath: net.paramPath)
program = try loader.load(device: inDevice, paramPointer: net.paramPointer!, paramSize: net.paramSize,modePointer:net.modelPointer!,modelSize:net.modelSize) program = try loader.load(device: inDevice, paramPointer: net.paramPointer!, paramSize: net.paramSize,modePointer:net.modelPointer!,modelSize:net.modelSize)
// program = try loader.load(device: inDevice, modelPath: net.modelPath, paraPath: net.paramPath)
net.updateProgram(program: program!)
executor = try Executor<Float32>.init(inDevice: inDevice, inQueue: inQueue, inProgram: program!) executor = try Executor<Float32>.init(inDevice: inDevice, inQueue: inQueue, inProgram: program!)
} catch let error { } catch let error {
print(error) print(error)
...@@ -114,12 +91,13 @@ public class Runner: NSObject { ...@@ -114,12 +91,13 @@ public class Runner: NSObject {
return true return true
} }
@objc public func predict(inputPointer: UnsafeMutablePointer<Float32>, completion: @escaping ( _ success: Bool, _ resultArray: [Float32]) -> Void) { @objc public func predict(inputPointer: UnsafeMutablePointer<Float32>, completion: @escaping ( _ success: Bool, _ result: PaddleMobileCPUResult?) -> Void) {
guard let res = cpuPaddleMobile?.predictInput(inputPointer, dim: dimsNum, means: meansNumber, scale: net.scale) else {
completion(false, []) guard let res = cpuPaddleMobile?.predictInput(inputPointer, dim: dimsNum) else {
completion(false, nil)
return return
} }
completion(true, res.map { ($0 as! NSNumber).floatValue }) completion(true, res)
} }
/** /**
...@@ -127,18 +105,18 @@ public class Runner: NSObject { ...@@ -127,18 +105,18 @@ public class Runner: NSObject {
* texture: 需要预测的 texture 需要做过预处理 * texture: 需要预测的 texture 需要做过预处理
* ( _ success: Bool, _ time:TimeInterval, _ resultArray: [Float32]) -> Void : 回调闭包, 三个参数分别为: 是否成功, 预测耗时, 结果数组 * ( _ success: Bool, _ time:TimeInterval, _ resultArray: [Float32]) -> Void : 回调闭包, 三个参数分别为: 是否成功, 预测耗时, 结果数组
*/ */
@objc public func predict(texture: MTLTexture, completion: @escaping ( _ success: Bool, _ resultArray: [Float32]) -> Void) { @objc public func predict(texture: MTLTexture, completion: @escaping ( _ success: Bool, _ result: ResultHolder?) -> Void) {
do { do {
try self.executor?.predict(input: texture, dim: [self.net.dim.n, self.net.dim.h, self.net.dim.w, self.net.dim.c], completionHandle: { [weak self] (res) in try self.executor?.predict(input: texture, dim: [self.net.dim.n, self.net.dim.h, self.net.dim.w, self.net.dim.c], completionHandle: { [weak self] (res) in
guard let SSelf = self else { guard let SSelf = self else {
fatalError( " self nil " ) fatalError( " self nil " )
} }
let resultArray = SSelf.net.fetchResult(paddleMobileRes: res) let result = SSelf.net.fetchResult(paddleMobileRes: res)
completion(true, resultArray) completion(true, result)
}, preProcessKernle: self.net.preprocessKernel, except: self.net.except) }, preProcessKernle: self.net.preprocessKernel, except: self.net.except)
} catch let error { } catch let error {
print(error) print(error)
completion(false, []) completion(false, nil)
return return
} }
} }
...@@ -148,21 +126,21 @@ public class Runner: NSObject { ...@@ -148,21 +126,21 @@ public class Runner: NSObject {
* cgImage: 需要预测的图片 * cgImage: 需要预测的图片
* ( _ success: Bool, _ time:TimeInterval, _ resultArray: [Float32]) -> Void : 回调闭包, 三个参数分别为: 是否成功, 预测耗时, 结果数组 * ( _ success: Bool, _ time:TimeInterval, _ resultArray: [Float32]) -> Void : 回调闭包, 三个参数分别为: 是否成功, 预测耗时, 结果数组
*/ */
@objc public func predict(cgImage: CGImage, completion: @escaping ( _ success: Bool, _ resultArray: [Float32]) -> Void) { // @objc public func predict(cgImage: CGImage, completion: @escaping ( _ success: Bool, _ resultArray: [Float32]) -> Void) {
if platform == .GPU { // if platform == .GPU {
getTexture(image: cgImage) { [weak self] (texture) in // getTexture(image: cgImage) { [weak self] (texture) in
guard let SSelf = self else { // guard let SSelf = self else {
fatalError( "" ) // fatalError( "" )
} // }
SSelf.predict(texture: texture, completion: completion) // SSelf.predict(texture: texture, completion: completion)
} // }
} else if platform == .CPU { // } else if platform == .CPU {
let input = preproccess(image: cgImage) // let input = preproccess(image: cgImage)
predict(inputPointer: input, completion: completion) // predict(inputPointer: input, completion: completion)
input.deinitialize(count: numel) // input.deinitialize(count: numel)
input.deallocate() // input.deallocate()
} // }
} // }
/* /*
* 清理内存, 调用此函数后, 不能再使用, 需重新 load * 清理内存, 调用此函数后, 不能再使用, 需重新 load
...@@ -193,10 +171,10 @@ public class Runner: NSObject { ...@@ -193,10 +171,10 @@ public class Runner: NSObject {
*/ */
@objc public func getTexture(image: CGImage, getTexture: @escaping (MTLTexture) -> Void) { @objc public func getTexture(image: CGImage, getTexture: @escaping (MTLTexture) -> Void) {
let texture = try? textureLoader?.newTexture(cgImage: image, options: [:]) ?! " texture loader error" let texture = try? textureLoader?.newTexture(cgImage: image, options: [:]) ?! " texture loader error"
scaleTexture(input: texture!, size: (net.dim.w, net.dim.h), complete: getTexture) scaleTexture(input: texture!, complete: getTexture)
} }
func scaleTexture(input: MTLTexture, size:(width: Int, height: Int), complete: @escaping (MTLTexture) -> Void) { public func scaleTexture(input: MTLTexture , complete: @escaping (MTLTexture) -> Void) {
guard let inQueue = queue, let inDevice = device else { guard let inQueue = queue, let inDevice = device else {
fatalError( " queue or devcie nil " ) fatalError( " queue or devcie nil " )
...@@ -206,7 +184,7 @@ public class Runner: NSObject { ...@@ -206,7 +184,7 @@ public class Runner: NSObject {
fatalError( " make buffer error" ) fatalError( " make buffer error" )
} }
let scaleKernel = ScaleKernel.init(device: inDevice, shape: CusomKernel.Shape.init(inWidth: size.width, inHeight: size.height, inChannel: 3)) let scaleKernel = ScaleKernel.init(device: inDevice, shape: CusomKernel.Shape.init(inWidth: net.dim.w, inHeight: net.dim.h, inChannel: 3))
do { do {
try scaleKernel.compute(inputTexuture: input, commandBuffer: buffer) try scaleKernel.compute(inputTexuture: input, commandBuffer: buffer)
......
...@@ -43,7 +43,15 @@ ...@@ -43,7 +43,15 @@
} }
-(void)predict:(id<MTLTexture>)texture withCompletion:(void (^)(BOOL, NSArray<NSNumber *> *))completion { -(void)predict:(id<MTLTexture>)texture withCompletion:(void (^)(BOOL, NSArray<NSNumber *> *))completion {
[runner predictWithTexture:texture completion:completion]; [runner predictWithTexture:texture completion:^(BOOL success, ResultHolder * _Nullable result) {
NSMutableArray<NSNumber *> *resultArray = [NSMutableArray arrayWithCapacity:result.capacity];
for (int i = 0; i < result.capacity; ++i) {
[resultArray addObject:[NSNumber numberWithFloat:result.result[i]]];
}
completion(success, resultArray);
}];
// [runner predictWithTexture:texture completion:completion];
} }
-(void)clear { -(void)clear {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
import Foundation import Foundation
struct BlockDesc { class BlockDesc {
let index: Int let index: Int
let parentIndex: Int let parentIndex: Int
let vars: [VarDesc] let vars: [VarDesc]
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
import Foundation import Foundation
struct OpDesc { class OpDesc {
let inputs: [String : [String]] let inputs: [String : [String]]
var paraInputs: [String : [String]] var paraInputs: [String : [String]]
var outputs: [String : [String]] var outputs: [String : [String]]
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
import Foundation import Foundation
public struct Program { public class Program {
let paramPath: String let paramPath: String
let programDesc: ProgramDesc let programDesc: ProgramDesc
let scope: Scope let scope: Scope
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
import Foundation import Foundation
public struct ProgramDesc { public class ProgramDesc {
var blocks: [BlockDesc] = [] var blocks: [BlockDesc] = []
init(protoProgram: PaddleMobile_Framework_Proto_ProgramDesc) { init(protoProgram: PaddleMobile_Framework_Proto_ProgramDesc) {
for block in protoProgram.blocks { for block in protoProgram.blocks {
......
...@@ -35,6 +35,22 @@ class Node { ...@@ -35,6 +35,22 @@ class Node {
type = inType type = inType
} }
subscript(index: Int) -> [Node] {
var nodes: [Node] = []
getNodesWithLocation(index: index, nowIndex: 0, nodes: &nodes)
return nodes
}
func getNodesWithLocation(index: Int, nowIndex: Int, nodes: inout [Node]) {
if index == nowIndex {
nodes.append(self)
}
for output in outputs {
output.getNodesWithLocation(index: index, nowIndex: nowIndex + 1, nodes: &nodes)
}
}
static func -->(lNode: Node, rNode: Node) -> Node { static func -->(lNode: Node, rNode: Node) -> Node {
lNode.outputs.append(rNode) lNode.outputs.append(rNode)
rNode.inputs.append(lNode) rNode.inputs.append(lNode)
...@@ -77,7 +93,7 @@ class Node { ...@@ -77,7 +93,7 @@ class Node {
for attr in inOpdesc.attrs { for attr in inOpdesc.attrs {
beginNode.opDesc?.attrs[attr.key] = attr.value beginNode.opDesc?.attrs[attr.key] = attr.value
// print(beginNode.opDesc?.attrs) // print(beginNode.opDesc?.attrs)
} }
for paraInput in inOpdesc.paraInputs { for paraInput in inOpdesc.paraInputs {
...@@ -119,6 +135,27 @@ class Node { ...@@ -119,6 +135,27 @@ class Node {
} }
} }
func relationship() -> [String : Node]{
var map: [String : Node] = [:]
relationship(map: &map)
return map
}
private func relationship(map: inout [String : Node]) {
guard let inOpDesc = opDesc else {
return
}
for output in inOpDesc.outputs {
for outputKey in output.value {
map[outputKey] = self
}
}
for output in outputs {
output.relationship(map: &map)
}
}
} }
...@@ -145,9 +182,11 @@ extension Node: Equatable { ...@@ -145,9 +182,11 @@ extension Node: Equatable {
class ProgramOptimize<P: PrecisionType> { class ProgramOptimize<P: PrecisionType> {
// register fusion // register fusion
let fusionOps: [Fusion.Type] = [ConvAddBatchNormReluOp<P>.self, let fusionOps: [Fusion.Type] = [ConvAddBatchNormReluOp<P>.self,
ConvAddPreluOp<P>.self,
ConvAddOp<P>.self, ConvAddOp<P>.self,
ConvBNReluOp<P>.self, ConvBNReluOp<P>.self,
DwConvBNReluOp<P>.self] DwConvBNReluOp<P>.self
]
func optimize(originProgramDesc: ProgramDesc) -> ProgramDesc { func optimize(originProgramDesc: ProgramDesc) -> ProgramDesc {
...@@ -157,7 +196,7 @@ class ProgramOptimize<P: PrecisionType> { ...@@ -157,7 +196,7 @@ class ProgramOptimize<P: PrecisionType> {
var mapForNodeChain: [String : Node] = [:] var mapForNodeChain: [String : Node] = [:]
var nodes: [Node] = [] var nodes: [Node] = []
var typeMapNodes: [String : [Node]] = [:] var typeMapNodes: [String : [(node: Node, output: [String : Node])]] = [:]
let block = originProgramDesc.blocks[0] let block = originProgramDesc.blocks[0]
for opDesc in block.ops { for opDesc in block.ops {
guard let opInputKeys = opInfos[opDesc.type]?.inputs, let outputKeys = opInfos[opDesc.type]?.outputs else { guard let opInputKeys = opInfos[opDesc.type]?.inputs, let outputKeys = opInfos[opDesc.type]?.outputs else {
...@@ -186,10 +225,10 @@ class ProgramOptimize<P: PrecisionType> { ...@@ -186,10 +225,10 @@ class ProgramOptimize<P: PrecisionType> {
nodes.append(node) nodes.append(node)
if var inNodes = typeMapNodes[opDesc.type] { if var inNodes = typeMapNodes[opDesc.type] {
inNodes.append(node) inNodes.append((node, mapForNodeChain))
typeMapNodes[opDesc.type] = inNodes typeMapNodes[opDesc.type] = inNodes
} else { } else {
typeMapNodes[opDesc.type] = [node] typeMapNodes[opDesc.type] = [(node, mapForNodeChain)]
} }
} }
...@@ -198,10 +237,34 @@ class ProgramOptimize<P: PrecisionType> { ...@@ -198,10 +237,34 @@ class ProgramOptimize<P: PrecisionType> {
let depth = fusionNode.depth() let depth = fusionNode.depth()
if let toMatchNodes = typeMapNodes[fusionNode.type] { if let toMatchNodes = typeMapNodes[fusionNode.type] {
for node in toMatchNodes { for node in toMatchNodes {
let toNode = node.to(depth: depth)
let toNode = node.node.to(depth: depth)
if toNode == fusionNode { // match if toNode == fusionNode { // match
var canFolder = true
let relationshipMap = toNode.relationship()
for toCheck in fusion.needCheck() {
// let nodes = toCheck
let checkNodes = toNode[toCheck.0]
for checkNode in checkNodes {
let inputToChecks = checkNode.opDesc?.inputs[toCheck.1] ?? []
for inputToCheck in inputToChecks {
if node.output[inputToCheck] == nil {
if relationshipMap[inputToCheck] == nil {
canFolder = false
}
}
}
}
}
if !canFolder {
continue
}
var removeNodes: [Node] = [] var removeNodes: [Node] = []
node.folderWith(fusion: fusion, removedNodes: &removeNodes) node.node.folderWith(fusion: fusion, removedNodes: &removeNodes)
for removeNode in removeNodes { for removeNode in removeNodes {
nodes.remove(element: removeNode) nodes.remove(element: removeNode)
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
import Foundation import Foundation
struct TensorDesc { class TensorDesc {
let dims: [Int] let dims: [Int]
let dataType: VarTypeType let dataType: VarTypeType
let dataLayout: DataLayout = DataLayout.NCHW() let dataLayout: DataLayout = DataLayout.NCHW()
......
...@@ -56,7 +56,7 @@ enum VarTypeType: Int { ...@@ -56,7 +56,7 @@ enum VarTypeType: Int {
} }
} }
struct VarDesc { class VarDesc {
let name: String let name: String
let persistable: Bool let persistable: Bool
let type: VarTypeType let type: VarTypeType
......
...@@ -14,39 +14,50 @@ ...@@ -14,39 +14,50 @@
import Foundation import Foundation
let testTo = 3
let testTo = 81
var isTest = false var isTest = false
let computePrecision: ComputePrecision = .Float16 let computePrecision: ComputePrecision = .Float16
public class ResultHolder { public class GPUResultHolder {
public let dim: [Int] public let dim: [Int]
public let resultArr: [Float32] public let capacity: Int
public var resultPointer: UnsafeMutablePointer<Float32>?
public var intermediateResults: [String : [Variant]]? public var intermediateResults: [String : [Variant]]?
public let elapsedTime: Double public let elapsedTime: Double
public init(inDim: [Int], inResult: [Float32], inElapsedTime: Double, inIntermediateResults: [String : [Variant]]? = nil) { public init(inDim: [Int], inPointer: UnsafeMutablePointer<Float32>?, inCapacity: Int, inElapsedTime: Double, inIntermediateResults: [String : [Variant]]? = nil) {
dim = inDim dim = inDim
resultArr = inResult capacity = inCapacity
if let inInPointer = inPointer {
resultPointer = UnsafeMutablePointer<Float32>.allocate(capacity: inCapacity)
resultPointer?.initialize(from: inInPointer, count: inCapacity)
}
elapsedTime = inElapsedTime elapsedTime = inElapsedTime
intermediateResults = inIntermediateResults intermediateResults = inIntermediateResults
} }
} }
extension ResultHolder: CustomDebugStringConvertible, CustomStringConvertible { extension GPUResultHolder: CustomDebugStringConvertible, CustomStringConvertible {
public var debugDescription: String { public var debugDescription: String {
var str = "" // var str = ""
str += "Dim: \(dim) \n value:[ " // str += "Dim: \(dim) \n value:[ "
if resultArr.count < 20 { // if resultArr.count < 20 {
for d in resultArr { // for d in resultArr {
str += " \(d) " // str += " \(d) "
} // }
} else { // } else {
for d in stride(from: 0, to: resultArr.count, by: resultArr.count/20) { // for d in stride(from: 0, to: resultArr.count, by: resultArr.count/20) {
str += " \(resultArr[d]) " // str += " \(resultArr[d]) "
} // }
} // }
str += " ]" // str += " ]"
return str // return str
fatalError()
} }
public var description: String { public var description: String {
...@@ -65,11 +76,23 @@ public class Executor<P: PrecisionType> { ...@@ -65,11 +76,23 @@ public class Executor<P: PrecisionType> {
program = inProgram program = inProgram
device = inDevice device = inDevice
queue = inQueue queue = inQueue
// print("before for ")
//print(program.scope.vars["fea_pyramid1_mbox_conf_flat.Flatten.output.1.tmp_0"])
for block in inProgram.programDesc.blocks { for block in inProgram.programDesc.blocks {
//block.ops.count //block.ops.count
for i in 0..<block.ops.count { for i in 0..<block.ops.count {
let op = block.ops[i] let op = block.ops[i]
do { do {
// print("in for i \(i): ")
// print(program.scope.vars["fea_pyramid1_mbox_conf_flat.Flatten.output.1.tmp_0"])
//
// if i == 56 {
// print(program.scope.vars["fea_pyramid1_mbox_conf_flat.Flatten.output.1.tmp_0"])
//
// }
let op = try OpCreator<P>.shared.creat(device: inDevice, opDesc: op, scope: inProgram.scope) let op = try OpCreator<P>.shared.creat(device: inDevice, opDesc: op, scope: inProgram.scope)
ops.append(op) ops.append(op)
} catch let error { } catch let error {
...@@ -79,7 +102,7 @@ public class Executor<P: PrecisionType> { ...@@ -79,7 +102,7 @@ public class Executor<P: PrecisionType> {
} }
} }
public func predict(input: MTLTexture, dim: [Int], completionHandle: @escaping (ResultHolder) -> Void, preProcessKernle: CusomKernel? = nil, except: Int = 0) throws { public func predict(input: MTLTexture, dim: [Int], completionHandle: @escaping (GPUResultHolder) -> Void, preProcessKernle: CusomKernel? = nil, except: Int = 0) throws {
guard let buffer = queue.makeCommandBuffer() else { guard let buffer = queue.makeCommandBuffer() else {
throw PaddleMobileError.predictError(message: "CommandBuffer is nil") throw PaddleMobileError.predictError(message: "CommandBuffer is nil")
} }
...@@ -101,7 +124,7 @@ public class Executor<P: PrecisionType> { ...@@ -101,7 +124,7 @@ public class Executor<P: PrecisionType> {
let inputTexture = InputTexture.init(inMTLTexture: resInput, inExpectDim: Dim.init(inDim: dim)) let inputTexture = InputTexture.init(inMTLTexture: resInput, inExpectDim: Dim.init(inDim: dim))
program.scope.setInput(input: inputTexture) program.scope.setInput(input: inputTexture)
//(ops.count - except) //(ops.count - except)
for i in 0..<ops.count { for i in 0..<(ops.count - except) {
let op = ops[i] let op = ops[i]
do { do {
try op.run(device: device, buffer: buffer) try op.run(device: device, buffer: buffer)
...@@ -112,51 +135,57 @@ public class Executor<P: PrecisionType> { ...@@ -112,51 +135,57 @@ public class Executor<P: PrecisionType> {
var outputTextures: [String : [Variant]]? var outputTextures: [String : [Variant]]?
if except > 0 { if except > 0 {
ops[ops.count - except].computeMiddleResult(device: device, buffer: buffer)
outputTextures = ops[ops.count - except].inputVariant() outputTextures = ops[ops.count - except].inputVariant()
} }
buffer.addCompletedHandler { [weak self] (commandbuffer) in buffer.addCompletedHandler { [weak self] (commandbuffer) in
// let inputArr = resInput.toTensor(dim: (n: dim[0], c: dim[3], h: dim[1], w: dim[2])) // let inputArr = resInput.toTensor(dim: (n: dim[0], c: dim[3], h: dim[1], w: dim[2]))
//// print(inputArr.strideArray()) // print(inputArr.strideArray())
//
// print(dim) //// print(dim)
// writeToLibrary(fileName: "test_image_ssd_ar", array: inputArr) // writeToLibrary(fileName: "test_image_ssd_ar", array: inputArr)
// print(" write done ")
// print("write to library done") // print("write to library done")
// return // return
// print(inputArr) // print(inputArr)
//
// let stridableInput: [(index: Int, value: Float)] = input.stridableFloatArray() // let stridableInput: [(index: Int, value: Float)] = input.stridableFloatArray()
// print(stridableInput) // print(stridableInput)
//
// let _: Flo? = input.logDesc(header: "input: ", stridable: true) // let _: Flo? = input.logDesc(header: "input: ", stridable: true)
// for i in 0..<self.ops.count { // for i in 0..<self!.ops.count {
// let op = self.ops[i] // let op = self!.ops[i]
// print(" 第 \(i) 个 op: ") // print(" 第 \(i) 个 op: ")
// op.delogOutput() // op.delogOutput()
// } // }
// return; // return;
// self.ops[testTo - 2].delogOutput() // self!.ops[testTo - 2].delogOutput()
// self.ops[testTo - 1].delogOutput() // self!.ops[testTo - 1].delogOutput()
// self.ops[60].delogOutput() // self!.ops[60].delogOutput()
// return // return
guard let SSelf = self else { guard let SSelf = self else {
// return
fatalError() fatalError()
} }
let afterDate = Date.init() let afterDate = Date.init()
var resultHolder: ResultHolder var resultHolder: GPUResultHolder
if except > 0 { if except > 0 {
resultHolder = ResultHolder.init(inDim: [], inResult: [], inElapsedTime: afterDate.timeIntervalSince(beforeDate), inIntermediateResults: outputTextures) resultHolder = GPUResultHolder.init(inDim: [], inPointer: nil, inCapacity: 0, inElapsedTime: afterDate.timeIntervalSince(beforeDate), inIntermediateResults: outputTextures)
} else { } else {
let outputVar: Variant = SSelf.program.scope.output()! let outputVar: Variant = SSelf.program.scope.output()!
let output: Texture<P> = outputVar as! Texture<P> let output: FetchHolder = outputVar as! FetchHolder
// let beforeToTensorDate = Date.init()
resultHolder = GPUResultHolder.init(inDim: output.dim, inPointer: output.result, inCapacity: output.capacity, inElapsedTime: afterDate.timeIntervalSince(beforeDate))
resultHolder = ResultHolder.init(inDim: output.dim.dims, inResult: output.toTensor(), inElapsedTime: afterDate.timeIntervalSince(beforeDate)) // let timeToTensor = Date.init().timeIntervalSince(beforeToTensorDate)
// print(timeToTensor)
} }
completionHandle(resultHolder) completionHandle(resultHolder)
......
...@@ -214,7 +214,7 @@ public class Loader<P: PrecisionType> { ...@@ -214,7 +214,7 @@ public class Loader<P: PrecisionType> {
} }
} else { } else {
if varDesc.name == fetchKey { if varDesc.name == fetchKey {
scope[varDesc.name] = ResultHolder.init(inDim: [], inResult: [], inElapsedTime: 0.0) // scope[varDesc.name] = ResultHolder.init(inDim: [], inResult: [], inCapacity: <#Int#>, inElapsedTime: 0.0)
} else if varDesc.name == feedKey { } else if varDesc.name == feedKey {
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册