diff --git a/Bender.xcodeproj/project.pbxproj b/Bender.xcodeproj/project.pbxproj index c0cc33e..2886593 100644 --- a/Bender.xcodeproj/project.pbxproj +++ b/Bender.xcodeproj/project.pbxproj @@ -18,7 +18,6 @@ 8F0669B71EC37424009F5C7C /* ParameterLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F0669B61EC37424009F5C7C /* ParameterLoader.swift */; }; 8F0669BA1EC3A31B009F5C7C /* PerLayerBinaryLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F0669B91EC3A31B009F5C7C /* PerLayerBinaryLoader.swift */; }; 8F0669BC1EC3A4C1009F5C7C /* SingleBinaryLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F0669BB1EC3A4C1009F5C7C /* SingleBinaryLoader.swift */; }; - 8F06933A1F352B3C0004D3E9 /* MetalPerformanceShadersStub.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F0693391F352B3C0004D3E9 /* MetalPerformanceShadersStub.framework */; }; 8F3DE15A1EBB962200D81949 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3DE1591EBB962200D81949 /* Network.swift */; }; 8F3DE15D1EBB9ACC00D81949 /* MetalShaderManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3DE15C1EBB9ACC00D81949 /* MetalShaderManager.swift */; }; 8F3DE15F1EBBD0C700D81949 /* Add.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3DE15E1EBBD0C700D81949 /* Add.swift */; }; @@ -177,7 +176,6 @@ files = ( 8FC2B3A51EE5D9B80038E582 /* SwiftProtobuf.framework in Frameworks */, 8F7C22321F30EE5B006DA176 /* MetalPerformanceShadersProxy.framework in Frameworks */, - 8F06933A1F352B3C0004D3E9 /* MetalPerformanceShadersStub.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c397ca..8e9e1d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,20 @@ # Change Log All notable changes to Bender will be documented in this file. -### [1.0.0](https://github.com/xmartlabs/Bender/releases/tag/1.0.0) - +### [0.2.0](https://github.com/xmartlabs/Bender/releases/tag/0.2.0) + + +* Adds Cocoapods & Carthage support. +* Adds [MetalPerformanceShadersProxy](https://github.com/xmartlabs/MetalPerformanceShadersProxy) in order to allow compilation on simulators. +* Adds support for Concat layer. +* Removes "convSize" constructor parameter from ResidualLayer. +* Fixes ordering issue while optimizing TensorFlow graph. +* Fixes memory usage issue. +* Fixes ConvTranspose layer. +* Adds optional dispatchQueue where to run. + +### [0.1.0](https://github.com/xmartlabs/Bender/releases/tag/0.1.0) + * This is the initial version. diff --git a/Cartfile b/Cartfile index 4796b42..79af9d2 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,2 @@ github "apple/swift-protobuf" "0.9.904" -github "xmartlabs/MetalPerformanceShadersProxy" ~> 0.1 +github "xmartlabs/MetalPerformanceShadersProxy" ~> 0.1.5 diff --git a/Cartfile.resolved b/Cartfile.resolved index 849907a..57e5641 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,2 +1,2 @@ -github "xmartlabs/MetalPerformanceShadersProxy" "0.1.3" github "apple/swift-protobuf" "0.9.904" +github "xmartlabs/MetalPerformanceShadersProxy" "0.1.5" diff --git a/Documentation/API.md b/Documentation/API.md index 78db5a3..1fab4b3 100644 --- a/Documentation/API.md +++ b/Documentation/API.md @@ -16,7 +16,7 @@ This document explains the basic API in __Bender__. To create a network model you can create it from scratch or [import](Importing.md) it from a TensorFlow graph. We will explain how to create a network from scratch: ```swift -let network = Network(device: device, +let network = Network(device: device, inputSize: inputSize, parameterLoader: loader) @@ -47,7 +47,7 @@ previousLayer ->> Add() ``` -In this case the output of `previousLayer` is passed to two different Convolution layers and then tthrough a normalization layer and after that they are added with the `Add` layer. +In this case the output of `previousLayer` is passed to two different Convolution layers and then through a normalization layer and after that they are added with the `Add` layer. After you finish adding layers to your network, you must call `network.initialize()` to finish setting up your network. @@ -138,7 +138,7 @@ The MetalShaderManager keeps all the custom kernel functions that an app has loa It also manages the function constants passed to these Metal functions. If you have a function that relies on function constants then you can pass them to the MetalShaderManager when you get your function. The function to get a kernel function is this: -```swift +```swift /// Get a MTLComputePipelineState with a Metal function of the given name /// /// - Parameters: @@ -196,4 +196,4 @@ A `CompositeLayer` is the same. It will be destroyed as soon as it is applied in [ParameterLoader]: #parameterloader [Creating custom layers]: #custom-layers [MetalShaderManager]: #metalshadermanager -[Composing Layers]: #composing-layers \ No newline at end of file +[Composing Layers]: #composing-layers diff --git a/Documentation/Importing.md b/Documentation/Importing.md index 4e054de..1b3c277 100644 --- a/Documentation/Importing.md +++ b/Documentation/Importing.md @@ -1,7 +1,7 @@ # Importing -Bender aims to be a lightweight framework that executes its neural networks on the GPU and also allows to import models from other frameworks without adding big binaries. +Bender aims to be a lightweight framework that executes its neural networks on the GPU and also allows to import models from other frameworks without adding big binaries. In the case of TensorFlow, you could use it to run code using Accelerate framework (CPU) but to include TensorFlow in your app you have to compile it as a static binary and it will add around 23 MB to your app (June 2017). Bender offers a lightweight solution which also uses the GPU for performance gain. @@ -38,7 +38,7 @@ let url = Bundle.main.url(forResource: "myGraph", withExtension: "pb")! let converter = TFConverter.default() // Convert graph -network.nodes = converter.convertGraph(file: url, type: .binary) +network.convert(converter: converter, url: url, type: .binary) // Initialize network network.initialize() @@ -50,9 +50,9 @@ network.initialize() ### Default `TFConverter` and limitations The default converter will make the following simplifications / optimizations: -* Remove subgraphs named with 'save', 'dropout', 'Regularizer' and 'Initializer' as this are training functions. There will certainly be more subgraphs added to this list in the future. This is implemented with `TFStripTrainingOps` and `TFDeleteDropout`. +* Remove subgraphs named with 'save', 'dropout', 'Regularizer' and 'Initializer' as these are training functions. There will certainly be more subgraphs added to this list in the future. This is implemented with `TFStripTrainingOps` and `TFDeleteDropout`. * Process Variables (`TFVariableProcessor`): It leaves only constant variables (not randomly initialized). -* Create FullyConnected (`TFDenseSubstitution`): In TF, the fully connected layer is implemented as a MatMul with an BiasAdd (or Add). If these nodes appear in the graph then they will be substitued by a 'FullyConnected' node. +* Create FullyConnected (`TFDenseSubstitution`): In TF, the fully connected layer is implemented as a MatMul with an BiasAdd (or Add). If these nodes appear in the graph then they will be substituted by a 'FullyConnected' node. * Remove Reshape (`TFReshapeOptimizer`): Removes reshape nodes from the graph. We should investigate if in future releases we want to do something else in this case. * Add bias to a Convolution (`TFConvOptimizer`). @@ -70,13 +70,13 @@ For __MPSCNNConvolution__ you need to pass [outputChannels, kernelHeight, kernel If the default optimizers do not fill your needs you might want to add custom optimizers. Also keep in mind that Bender does not support every function implemented in TensorFlow so it might be that you use not supported ops. In this case you can create a custom layer as explained below. We are open to receive Pull Requests implementing more layers. To create an optimizer, create a class that conforms to `TFOptimizer`. -A TFOptimizer does just have one simple function: +A TFOptimizer does just have one simple function: ```swift func optimize(graph: TFGraph) ``` -After you create the optimizer, you have to add it to your `TFConverter` like this; +After you create the optimizer, you have to add it to your `TFConverter` like this: ```swift let converter = TFConverter.default() diff --git a/Documentation/Supported_Layers.md b/Documentation/Supported_Layers.md index 0593b6d..28278e7 100644 --- a/Documentation/Supported_Layers.md +++ b/Documentation/Supported_Layers.md @@ -30,9 +30,9 @@ Also there are some layers that can be used for pre and post processing or which Last but not least, there is a _CompositeLayer_ included: -* __Residual__: A Residual layer contains a group of sublayers which are executed and the ouput is the result of this sublayers added to the input of the residual layer. - +* __Residual__: A Residual layer contains a group of sublayers which are executed and the output is the result of this sublayers added to the input of the residual layer. +## TensorFlow Mapping The following are the TensorFlow ops that are mapped to Bender layers: * __Add__ -> Add (works for two textures/tensors of the same size) diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index 19d40c4..102ea1d 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -15,8 +15,6 @@ 28F828DA1C4B714D00330CF4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 28F828D81C4B714D00330CF4 /* LaunchScreen.storyboard */; }; 46FAFCBD1F02CB89008754E1 /* ConcatTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46FAFCBC1F02CB89008754E1 /* ConcatTest.swift */; }; 46FAFCC11F04142C008754E1 /* ConstantLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46FAFCC01F04142C008754E1 /* ConstantLayer.swift */; }; - 8F0693371F3527F60004D3E9 /* MetalPerformanceShadersStub.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F0693361F3527F60004D3E9 /* MetalPerformanceShadersStub.framework */; }; - 8F0693381F3527F60004D3E9 /* MetalPerformanceShadersStub.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8F0693361F3527F60004D3E9 /* MetalPerformanceShadersStub.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8F28C68D1ED724BE0062039F /* g_and_w.pb in Resources */ = {isa = PBXBuildFile; fileRef = 8F28C68C1ED724BE0062039F /* g_and_w.pb */; }; 8F4466D01ECF756B00915819 /* UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4466CF1ECF756B00915819 /* UIImage.swift */; }; 8F46BCAD1EE0B52D00DF275A /* mnist-conv1_b in Resources */ = {isa = PBXBuildFile; fileRef = 8F46BCA51EE0B52D00DF275A /* mnist-conv1_b */; }; @@ -75,7 +73,6 @@ files = ( CFC14FFA1F396B6A00ACC4A1 /* MetalBender.framework in Embed Frameworks */, 8F7C22351F30EE6E006DA176 /* MetalPerformanceShadersProxy.framework in Embed Frameworks */, - 8F0693381F3527F60004D3E9 /* MetalPerformanceShadersStub.framework in Embed Frameworks */, 8FCD3EA81ED8BE1F00B1AAE6 /* SwiftProtobuf.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -140,7 +137,6 @@ files = ( CFC14FF91F396B6A00ACC4A1 /* MetalBender.framework in Frameworks */, 8F7C22341F30EE6E006DA176 /* MetalPerformanceShadersProxy.framework in Frameworks */, - 8F0693371F3527F60004D3E9 /* MetalPerformanceShadersStub.framework in Frameworks */, 8FCD3EA71ED8BE1F00B1AAE6 /* SwiftProtobuf.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme index c540d5a..5ef96ad 100644 --- a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme @@ -42,6 +42,16 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + 'https://github.com/xmartlabs/Bender.git' +pod 'MetalBender', '~> 0.2' ``` > Remember that Bender compiles for iOS 10. So you must add `platform :ios, '10.0'` to your Podfile @@ -132,7 +133,7 @@ pod 'MetalBender', :git => 'https://github.com/xmartlabs/Bender.git' To install Bender, add the following line to your Cartfile: ```ogdl -github "xmartlabs/Bender" +github "xmartlabs/Bender" ~> 0.2 ``` Then run: @@ -141,7 +142,7 @@ Then run: carthage update --platform iOS ``` -Finally, drag the built `.framework` binaries for `MetalBender`, `MetalPerformanceShadersProxy`, `MetalPerformanceShadersStub` and `SwiftProtobuf` to your application's Xcode project. +Finally, drag the built `.framework` binaries for `MetalBender`, `MetalPerformanceShadersProxy` and `SwiftProtobuf` to your application's Xcode project. ## Author