| //===----------------------------------------------------------------------===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2017 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| //===----------------------------------------------------------------------===// |
| |
| import Swift |
| @_exported import Accelerate |
| @_exported import Accelerate.vecLib.BNNS |
| |
| %{ |
| bnns2016 = [ |
| ('OSX','10.12'), ('iOS','10.0'), ('tvOS','10.0'), ('watchOS','3.0') |
| ] |
| |
| bnns2017 = [ |
| ('OSX','10.13'), ('iOS','11.0'), ('tvOS','11.0'), ('watchOS','4.0') |
| ] |
| |
| def relString(releases): |
| if not releases: |
| return '*' |
| return ', '.join([ |
| r[0] + ' ' + r[1] for r in releases |
| ] + ['*']) |
| |
| def available(releases): |
| return '@available(' + relString(releases) + ')' |
| |
| def renamed(name, rel=None): |
| return '\n'.join([ |
| available(rel), |
| '@available(*, deprecated, renamed: "' + name + '")' |
| ]) |
| |
| def newEnumValue(base, new, old, rel): |
| decl = ' public static var ' + new + ': ' + base + ' {\n' |
| impl = ' return __' + base + old + '\n }' |
| return ' ' + available(rel) + '\n' + decl + impl |
| |
| def oldEnumValue(base, new, old, oldRel): |
| return renamed(base + '.' + new, oldRel) + '\n' + \ |
| 'public var ' + base + old + ' = __' + base + old |
| |
| def renameEnumMembers(base, baseRel, names): |
| return available(baseRel) + \ |
| '\nextension ' + base + ' {\n' + \ |
| '\n'.join([newEnumValue(base, new, old, rel) for new, old, rel in names]) + '\n}\n' + \ |
| '\n'.join([oldEnumValue(base, new, old, rel) for new, old, rel in names if rel != bnns2017]) |
| }% |
| |
| ${renameEnumMembers('BNNSDataType', bnns2016, [ |
| ('float16', 'Float16', bnns2016), |
| ('float', 'Float32', bnns2016), |
| ('int8', 'Int8', bnns2016), |
| ('int16', 'Int16', bnns2016), |
| ('int32', 'Int32', bnns2016), |
| ('uint8', 'UInt8', bnns2017), |
| ('uint16', 'UInt16', bnns2017), |
| ('uint32', 'UInt32', bnns2017), |
| ('indexed8','Indexed8',bnns2016), |
| ])} |
| |
| ${renameEnumMembers('BNNSPoolingFunction', bnns2016, [ |
| ('max', 'Max', bnns2016), |
| ('average', 'Average', bnns2016), |
| ])} |
| |
| ${renameEnumMembers('BNNSActivationFunction', bnns2016, [ |
| ('identity', 'Identity', bnns2016), |
| ('rectifiedLinear', 'RectifiedLinear', bnns2016), |
| ('leakyRectifiedLinear', 'LeakyRectifiedLinear', bnns2016), |
| ('sigmoid', 'Sigmoid', bnns2016), |
| ('tanh', 'Tanh', bnns2016), |
| ('scaledTanh', 'ScaledTanh', bnns2016), |
| ('abs', 'Abs', bnns2016), |
| ('linear', 'Linear', bnns2017), |
| ('clamp', 'Clamp', bnns2017), |
| ('integerLinearSaturate', 'IntegerLinearSaturate', bnns2017), |
| ('integerLinearSaturatePerChannel', 'IntegerLinearSaturatePerChannel', bnns2017), |
| ('softmax', 'Softmax', bnns2017), |
| ])} |
| |
| ${renameEnumMembers('BNNSFlags', bnns2016, [('useClientPointer', 'UseClientPtr', bnns2016)])} |
| |
| ${available(bnns2016)} |
| extension BNNSImageStackDescriptor { |
| ${available(bnns2016)} |
| public init(width: Int, |
| height: Int, |
| channels: Int, |
| row_stride: Int, |
| image_stride: Int, |
| data_type: BNNSDataType) { |
| |
| _precondition(data_type != .indexed8, |
| "Image stacks cannot use the indexed8 data type.") |
| |
| self.init(width: width, |
| height: height, |
| channels: channels, |
| row_stride: row_stride, |
| image_stride: image_stride, |
| data_type: data_type, |
| data_scale: 1, |
| data_bias: 0) |
| } |
| } |
| |
| ${available(bnns2016)} |
| extension BNNSVectorDescriptor { |
| ${available(bnns2016)} |
| public init(size: Int, |
| data_type: BNNSDataType) { |
| |
| _precondition(data_type != .indexed8, |
| "Vectors cannot use the indexed8 data type.") |
| |
| self.init(size: size, |
| data_type: data_type, |
| data_scale: 1, |
| data_bias: 0) |
| } |
| } |
| |
| ${available(bnns2016)} |
| extension BNNSLayerData { |
| ${available(bnns2016)} |
| public init(data: UnsafeRawPointer?, |
| data_type: BNNSDataType, |
| data_scale: Float = 1, |
| data_bias: Float = 0) { |
| |
| _precondition(data_type != .indexed8, |
| "This initializer cannot be used with the indexed8 data type; use BNNSLayerData.indexed8 instead.") |
| |
| self.init(data: data, |
| data_type: data_type, |
| data_scale: data_scale, |
| data_bias: data_bias, |
| data_table: nil) |
| } |
| |
| ${available(bnns2016)} |
| public static var zero: BNNSLayerData { |
| return BNNSLayerData() |
| } |
| |
| /// A BNNSLayerData object with the indexed8 data type. |
| ${available(bnns2016)} |
| public static func indexed8(data: UnsafePointer<Int8>?, |
| data_table: UnsafePointer<Float>) |
| -> BNNSLayerData { |
| return BNNSLayerData(data: data, |
| data_type: .indexed8, |
| data_scale: 1, // unused |
| data_bias: 0, // unused |
| data_table: data_table) |
| } |
| } |
| |
| ${available(bnns2016)} |
| extension BNNSActivation { |
| |
| ${available(bnns2016)} |
| public init(function: BNNSActivationFunction, |
| alpha: Float = .nan, |
| beta: Float = .nan) { |
| if #available(OSX 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) { |
| _precondition(function != .integerLinearSaturate, |
| "This initializer cannot be used with the integerLinearSaturate activation function; use BNNSActivation.integerLinearSaturate(scale:Int32, offset:Int32, shift:Int32) instead.") |
| _precondition(function != .integerLinearSaturatePerChannel, |
| "This initializer cannot be used with the integerLinearSaturatePerChannel activation function; use BNNSActivation.integerLinearSaturatePerChannel(scale:UnsafePointer<Int32>, offset:UnsafePointer<Int32>, shift:UnsafePointer<Int32>) instead.") |
| } |
| self.init(function: function, |
| alpha: alpha, |
| beta: beta, |
| iscale: 1, // unused |
| ioffset: 0, // unused |
| ishift: 0, // unused |
| iscale_per_channel: nil, // unused |
| ioffset_per_channel: nil, // unused |
| ishift_per_channel: nil) // unused |
| } |
| |
| /// A BNNSActivation object that uses the identity activation function. |
| ${available(bnns2016)} |
| public static var identity: BNNSActivation { |
| return BNNSActivation(function: .identity) |
| } |
| |
| /// A BNNSActivation object that uses the integerLinearSaturate |
| /// activation function. |
| ${available(bnns2017)} |
| public static func integerLinearSaturate( |
| scale: Int32 = 1, |
| offset: Int32 = 0, |
| shift: Int32 = 0) |
| -> BNNSActivation { |
| return BNNSActivation(function: .integerLinearSaturate, |
| alpha: .nan, // unused |
| beta: .nan, // unused |
| iscale: scale, |
| ioffset: offset, |
| ishift: shift, |
| iscale_per_channel: nil, // unused |
| ioffset_per_channel: nil,// unused |
| ishift_per_channel: nil) // unused |
| } |
| |
| /// A BNNSActivation object that uses the integerLinearSaturatePerChannel |
| /// activation function. |
| /// |
| /// `scale`, `offset`, and `shift` must each point to a buffer with count |
| /// equal to the number of channels on which this activation object operates. |
| ${available(bnns2017)} |
| public static func integerLinearSaturatePerChannel( |
| scale: UnsafePointer<Int32>, |
| offset: UnsafePointer<Int32>, |
| shift: UnsafePointer<Int32>) |
| -> BNNSActivation { |
| return BNNSActivation(function: .integerLinearSaturatePerChannel, |
| alpha: .nan, // unused |
| beta: .nan, // unused |
| iscale: 1, // unused |
| ioffset: 0, // unused |
| ishift: 0, // unused |
| iscale_per_channel: scale, |
| ioffset_per_channel: offset, |
| ishift_per_channel: shift) |
| } |
| } |
| |
| ${available(bnns2016)} |
| extension BNNSConvolutionLayerParameters { |
| ${available(bnns2016)} |
| public init(x_stride: Int, |
| y_stride: Int, |
| x_padding: Int, |
| y_padding: Int, |
| k_width: Int, |
| k_height: Int, |
| in_channels: Int, |
| out_channels: Int, |
| weights: BNNSLayerData) { |
| self.init(x_stride: x_stride, |
| y_stride: y_stride, |
| x_padding: x_padding, |
| y_padding: y_padding, |
| k_width: k_width, |
| k_height: k_height, |
| in_channels: in_channels, |
| out_channels: out_channels, |
| weights: weights, |
| bias: .zero, |
| activation: .identity) |
| } |
| } |
| |
| ${available(bnns2016)} |
| extension BNNSPoolingLayerParameters { |
| ${available(bnns2016)} |
| public init(x_stride: Int, |
| y_stride: Int, |
| x_padding: Int, |
| y_padding: Int, |
| k_width: Int, |
| k_height: Int, |
| in_channels: Int, |
| out_channels: Int, |
| pooling_function: BNNSPoolingFunction) { |
| self.init(x_stride: x_stride, |
| y_stride: y_stride, |
| x_padding: x_padding, |
| y_padding: y_padding, |
| k_width: k_width, |
| k_height: k_height, |
| in_channels: in_channels, |
| out_channels: out_channels, |
| pooling_function: pooling_function, |
| bias: .zero, |
| activation: .identity) |
| } |
| } |
| |
| ${available(bnns2016)} |
| extension BNNSFullyConnectedLayerParameters { |
| ${available(bnns2016)} |
| public init(in_size: Int, |
| out_size: Int, |
| weights: BNNSLayerData) { |
| self.init(in_size: in_size, |
| out_size: out_size, |
| weights: weights, |
| bias: .zero, |
| activation: .identity) |
| } |
| } |