Skip to content
This repository has been archived by the owner on Jan 25, 2021. It is now read-only.

Commit

Permalink
Redesign API so that Memory saving in ForwardGraph class.
Browse files Browse the repository at this point in the history
  • Loading branch information
pcpLiu committed Nov 9, 2017
1 parent e4ebc30 commit dcfe1ff
Show file tree
Hide file tree
Showing 24 changed files with 574 additions and 834 deletions.
1 change: 1 addition & 0 deletions .mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pages:
- Get started:
- 'Install': 'Getting started/Install.md'
- 'Quick Start: SimpleCNN': 'Getting started/Quick Start Simple CNN.md'
- 'Forward Computation': 'Getting started/Forward Computation.md'
- 'Core Concepts':
- 'Tensor': 'Getting started/Core concepts/Tensor.md'
- 'Operator': 'Getting started/Core concepts/Operator.md'
Expand Down
5 changes: 2 additions & 3 deletions Examples/Graph/SimpleCNN.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import XCTest
@testable import Serrano

func configureSimpleCNN() -> ComputationGraph {
let g = ComputationGraph()
func configureSimpleCNN() -> ForwardGraph {
let g = ForwardGraph()
let shape = TensorShape(dataType: .float, shape: [244, 244, 3]) // shape of the tensor
let input = g.tensor(shape: shape) // add an input tensor

Expand Down Expand Up @@ -52,7 +52,6 @@ class SimpleCNN: XCTestCase {
let _ = SerranoEngine.configuredEngine.configureEngine(computationMode: .GPU)

let g = configureSimpleCNN()
g.allocateAllTensors()
g.forwardPrepare()

// calculate
Expand Down
7 changes: 3 additions & 4 deletions Examples/Graph/VGG16.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ This code shows how to construct a VGG16 network using graph's low-level API.

[vgg16](http://book.paddlepaddle.org/03.image_classification/image/vgg16.png)
*/
func configureVGG16() -> ComputationGraph {
let g = ComputationGraph()
func configureVGG16() -> ForwardGraph {
let g = ForwardGraph()

// input [244, 244, 3]
let shape = TensorShape(dataType: .float, shape: [244, 244, 3])
Expand Down Expand Up @@ -157,9 +157,8 @@ class Example_VGG16: XCTestCase {

let _ = SerranoEngine.configuredEngine.configureEngine(computationMode: .GPU)
let vgg16 = configureVGG16()
vgg16.allocateAllTensors()
vgg16.forwardPrepare()

let start = CFAbsoluteTimeGetCurrent()
// vgg16.forward(mode: .CPU)
vgg16.forward(mode: .GPU)
Expand Down
5 changes: 5 additions & 0 deletions Source/Serrano/core/resource_manager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public struct MTLBufferResource {
/// Offset from the buffer base address.
/// Used by sliced tensor object.
var offset: Int

public init(buffer: MTLBuffer, offset: Int) {
self.buffer = buffer
self.offset = offset
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
14 changes: 8 additions & 6 deletions Source/Serrano/core/symbol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@ public enum SymbolType {
}
}




/// The Data source of a data symbol (Tensor or scalar symbol)
/// The Data source of a data symbol
public enum SymbolDataSource {
/// Symbol explicitly created by user and needs feeding from user
/// Symbol explicitly created by user and needs feeding from user, like Input of graph.
case User

/// Symbol gets data from a calculation result, so no need sfeeding from user
/// Symbol gets data from a calculation result, so no need sfeeding from user.
/// For example, output of operator symbols inside a graph.
case Calculation

/// Parameter data source.
/// This measn a datay symbol's binded data is parameter.
case Parameter

/// Symbol has a default value but also can receive data from user,
/// like some parameters of operators.
case Default
Expand Down
57 changes: 53 additions & 4 deletions Source/Serrano/core/tensor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,10 @@ public class Tensor: Hashable, Equatable, TensorSymbol {
/// The index array of this slice object in raw tensor.
/// `nil` if not a sliced tensor
internal var _sliceIndex: [Int]?

/// `MTLBuffer` binded to this tensor.
/// - Note: If the tensor is sliced, this is `nil`.
internal var _mtlbuffer: MTLBuffer?

/// Count of data elements tored
public var count: Int {
Expand Down Expand Up @@ -782,15 +786,13 @@ public class Tensor: Hashable, Equatable, TensorSymbol {

/// Designated init.
///
/// - Note: Usually, user should not call this init directly.
///
/// - Parameters:
/// - shape: shape
/// - allocateSize: allocateSize
/// - capacity: capacity
/// - dataMemoryBaseAddres: dataMemoryBaseAddres
/// - elementReader: elementReader
public init(shape: TensorShape, allocateSize: Int, capacity: Int,
internal init(shape: TensorShape, allocateSize: Int, capacity: Int,
dataMemoryBaseAddres: UnsafeMutablePointer<Float>, elementReader:UnsafeMutableBufferPointer<Float>) {
self._shape = shape
self._allocatedSize = allocateSize
Expand Down Expand Up @@ -880,6 +882,24 @@ public class Tensor: Hashable, Equatable, TensorSymbol {

}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MARK: - Make tensors randomly

/// Generate a random tensor.
///
/// - Parameters:
/// - shape:
/// - min:
/// - max:
/// - Returns:
public static func randomTensor(_ shape: TensorShape, min: Float = 0.0, max: Float = 1.0) -> Tensor {
let tensor = Tensor(repeatingValue: 0.0, tensorShape: shape)
for i in 0..<tensor.count {
tensor.floatValueReader[i] = RandomValueGenerator.randomFloat(min: min, max: max)
}
return tensor
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MARK: - Util methods
Expand Down Expand Up @@ -935,7 +955,7 @@ public class Tensor: Hashable, Equatable, TensorSymbol {
///
/// - Parameter tensor: cp from tensor
public func copyValues(_ tensor: Tensor) {
let copyOp = CopyOperator(inputTensors: [self], outputTensors: [tensor])
let copyOp = CopyOperator(inputTensors: [tensor], outputTensors: [self])
copyOp.compute()
}

Expand Down Expand Up @@ -1012,6 +1032,35 @@ public class Tensor: Hashable, Equatable, TensorSymbol {
return lhs._dataMemoryBaseAdrress == rhs._dataMemoryBaseAdrress
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MARK: - Metal Buffer Binding APIs


/// Get a `MTLBuffer` associated with this tensor object.
///
/// - Returns:
public func gpuBufferResource() -> MTLBufferResource {
// check gpu available
guard SerranoEngine.configuredEngine.hasAvailableGPU() else {
SerranoLogging.errorLogging(message: "No available GPU device.",
file: "\(#file)", function: "\(#function)", line: "\(#line)")
fatalError("Fatal error raised by Serrano. Check log for details.")
}

if self.isSliceTensor {
return MTLBufferResource(buffer: self.sliceRootTensor!.gpuBufferResource().buffer,
offset: self.sliceRootTensor!.slicedTensorOffset(self)!)
} else {
if self._mtlbuffer == nil {
self._mtlbuffer = SerranoEngine.configuredEngine.GPUDevice!.makeBuffer(bytesNoCopy: self._dataMemoryBaseAdrress,
length: self.allocatedBytes,
options: MTLResourceOptions.storageModeShared)
}
return MTLBufferResource(buffer: self._mtlbuffer!, offset: 0)
}
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MARK: - Tensor manipulation

Expand Down
Loading

0 comments on commit dcfe1ff

Please sign in to comment.