SignatureRunner

import Foundation
import TensorFlowLiteC
#if os(Linux)
  import SwiftGlibc
#else
  import Darwin
#endif
/// A TensorFlow Lite model signature runner. You can get a `SignatureRunner` instance for a
/// signature from an `Interpreter` and then use the SignatureRunner APIs.
///
/// - Note: `SignatureRunner` instances are *not* thread-safe.
/// - Note: Each `SignatureRunner` instance is associated with an `Interpreter` instance. As long
///     as a `SignatureRunner` instance is still in use, its associated `Interpreter` instance
///     will not be deallocated.
public final class SignatureRunner {
  /// The signature key.
  public let signatureKey: String
  /// The SignatureDefs input names.
  public var inputs: [String] {
    guard let inputs = _inputs else {
      let inputCount = Int(TfLiteSignatureRunnerGetInputCount(self.cSignatureRunner))
      let ins: [String] = (0..<inputCount).map {
        guard
          let inputNameCString = TfLiteSignatureRunnerGetInputName(
            self.cSignatureRunner, Int32($0))
        else {
          return ""
        }
        return String(cString: inputNameCString)
      }
      _inputs = ins
      return ins
    }
    return inputs
  }
  /// The SignatureDefs output names.
  public var outputs: [String] {
    guard let outputs = _outputs else {
      let outputCount = Int(TfLiteSignatureRunnerGetOutputCount(self.cSignatureRunner))
      let outs: [String] = (0..<outputCount).map {
        guard
          let outputNameCString = TfLiteSignatureRunnerGetOutputName(
            self.cSignatureRunner, Int32($0))
        else {
          return ""
        }
        return String(cString: outputNameCString)
      }
      _outputs = outs
      return outs
    }
    return outputs
  }
  /// The backing interpreter. It's a strong reference to ensure that the interpreter is never
  /// released before this signature runner is released.
  ///
  /// - Warning: Never let the interpreter hold a strong reference to the signature runner to avoid
  ///     retain cycles.
  private var interpreter: Interpreter
  /// The `TfLiteSignatureRunner` C pointer type represented as an
  /// `UnsafePointer<TfLiteSignatureRunner>`.
  private typealias CSignatureRunner = OpaquePointer
  /// The `TfLiteTensor` C pointer type represented as an
  /// `UnsafePointer<TfLiteTensor>`.
  private typealias CTensor = UnsafePointer<TfLiteTensor>?
  /// The underlying `TfLiteSignatureRunner` C pointer.
  private var cSignatureRunner: CSignatureRunner
  /// Whether we need to allocate tensors memory.
  private var isTensorsAllocationNeeded: Bool = true
  /// The SignatureDefs input names.
  private var _inputs: [String]?
  /// The SignatureDefs output names.
  private var _outputs: [String]?
  // MARK: Initializers
  /// Initializes a new TensorFlow Lite signature runner instance with the given interpreter and
  /// signature key.
  ///
  /// - Parameters:
  ///   - interpreter: The TensorFlow Lite model interpreter.
  ///   - signatureKey: The signature key.
  /// - Throws: An error if fail to create the signature runner with given key.
  internal init(interpreter: Interpreter, signatureKey: String) throws {
    guard let signatureKeyCString = signatureKey.cString(using: String.Encoding.utf8),
      let cSignatureRunner = TfLiteInterpreterGetSignatureRunner(
        interpreter.cInterpreter, signatureKeyCString)
    else {
      throw SignatureRunnerError.failedToCreateSignatureRunner(signatureKey: signatureKey)
    }
    self.cSignatureRunner = cSignatureRunner
    self.signatureKey = signatureKey
    self.interpreter = interpreter
    try allocateTensors()
  }
  deinit {
    TfLiteSignatureRunnerDelete(cSignatureRunner)
  }
  // MARK: Public
  /// Invokes the signature with given input data.
  ///
  /// - Parameters:
  ///   - inputs: A map from input name to the input data. The input data will be copied into the
  ///       input tensor.
  public func invoke(with inputs: [String: Data]) throws {
    try allocateTensors()
    for (inputName, inputData) in inputs {
      try copy(inputData, toInputNamed: inputName)
    }
    guard TfLiteSignatureRunnerInvoke(self.cSignatureRunner) == kTfLiteOk else {
      throw SignatureRunnerError.failedToInvokeSignature(signatureKey: signatureKey)
    }
  }
  /// Returns the input tensor with the given input name in the signature.
  ///
  /// - Parameters:
  ///   - name: The input name in the signature.
  /// - Throws: An error if fail to get the input `Tensor` or the `Tensor` is invalid.
  /// - Returns: The input `Tensor` with the given input name.
  public func input(named name: String) throws -> Tensor {
    return try tensor(named: name, withType: TensorType.input)
  }
  /// Returns the output tensor with the given output name in the signature.
  ///
  /// - Parameters:
  ///   - name: The output name in the signature.
  /// - Throws: An error if fail to get the output `Tensor` or the `Tensor` is invalid.
  /// - Returns: The output `Tensor` with the given output name.
  public func output(named name: String) throws -> Tensor {
    return try tensor(named: name, withType: TensorType.output)
  }
  /// Resizes the input `Tensor` with the given input name to the specified `Tensor.Shape`.
  ///
  /// - Note: After resizing an input tensor, the client **must** explicitly call
  ///     `allocateTensors()` before attempting to access the resized tensor data.
  /// - Parameters:
  ///   - name: The input name of the `Tensor`.
  ///   - shape: The shape to resize the input `Tensor` to.
  /// - Throws: An error if the input tensor with given input name could not be resized.
  public func resizeInput(named name: String, toShape shape: Tensor.Shape) throws {
    guard let inputNameCString = name.cString(using: String.Encoding.utf8),
      TfLiteSignatureRunnerResizeInputTensor(
        self.cSignatureRunner,
        inputNameCString,
        shape.int32Dimensions,
        Int32(shape.rank)
      ) == kTfLiteOk
    else {
      throw SignatureRunnerError.failedToResizeInputTensor(inputName: name)
    }
    isTensorsAllocationNeeded = true
  }
  ///
  /// - Parameters:
  ///   - data: The data to be copied to the input `Tensor`'s data buffer.
  ///   - name: The input name of the `Tensor`.
  /// - Throws: An error if fail to get the input `Tensor` or if the `data.count` does not match the
  ///     input tensor's `data.count`.
  /// - Returns: The input `Tensor` with the copied data.
  public func copy(_ data: Data, toInputNamed name: String) throws {
    guard let inputNameCString = name.cString(using: String.Encoding.utf8),
      let cTensor = TfLiteSignatureRunnerGetInputTensor(self.cSignatureRunner, inputNameCString)
    else {
      throw SignatureRunnerError.failedToGetTensor(tensorType: "input", nameInSignature: name)
    }
    let byteCount = TfLiteTensorByteSize(cTensor)
    guard data.count == byteCount else {
      throw SignatureRunnerError.invalidTensorDataCount(provided: data.count, required: byteCount)
    }
    #if swift(>=5.0)
      let status = data.withUnsafeBytes {
        TfLiteTensorCopyFromBuffer(cTensor, $0.baseAddress, data.count)
      }
    #else
      let status = data.withUnsafeBytes { TfLiteTensorCopyFromBuffer(cTensor, $0, data.count) }
    #endif  // swift(>=5.0)
    guard status == kTfLiteOk else { throw SignatureRunnerError.failedToCopyDataToInputTensor }
  }
  /// Allocates memory for tensors.
  /// - Note: This is a relatively expensive operation and this call is *purely optional*.
  ///     Tensor allocation will occur automatically during execution.
  /// - Throws: An error if memory could not be allocated for the tensors.
  public func allocateTensors() throws {
    if !isTensorsAllocationNeeded { return }
    guard TfLiteSignatureRunnerAllocateTensors(self.cSignatureRunner) == kTfLiteOk else {
      throw SignatureRunnerError.failedToAllocateTensors
    }
    isTensorsAllocationNeeded = false
  }
  // MARK: - Private
  /// Returns the I/O tensor with the given name in the signature.
  ///
  /// - Parameters:
  ///   - nameInSignature: The input or output name in the signature.
  ///   - type: The tensor type.
  /// - Throws: An error if fail to get the `Tensor` or the `Tensor` is invalid.
  /// - Returns: The `Tensor` with the given name in the signature.
  private func tensor(named nameInSignature: String, withType type: TensorType) throws -> Tensor {
    guard let nameInSignatureCString = nameInSignature.cString(using: String.Encoding.utf8)
    else {
      throw SignatureRunnerError.failedToGetTensor(
        tensorType: type.rawValue, nameInSignature: nameInSignature)
    }
    var cTensorPointer: CTensor
    switch type {
    case .input:
      cTensorPointer = UnsafePointer(
        TfLiteSignatureRunnerGetInputTensor(self.cSignatureRunner, nameInSignatureCString))
    case .output:
      cTensorPointer = TfLiteSignatureRunnerGetOutputTensor(
        self.cSignatureRunner, nameInSignatureCString)
    }
    guard let cTensor = cTensorPointer else {
      throw SignatureRunnerError.failedToGetTensor(
        tensorType: type.rawValue, nameInSignature: nameInSignature)
    }
    guard let bytes = TfLiteTensorData(cTensor) else {
      throw SignatureRunnerError.allocateTensorsRequired
    }
    guard let dataType = Tensor.DataType(type: TfLiteTensorType(cTensor)) else {
      throw SignatureRunnerError.invalidTensorDataType
    }
    let nameCString = TfLiteTensorName(cTensor)
    let name = nameCString == nil ? "" : String(cString: nameCString!)
    let byteCount = TfLiteTensorByteSize(cTensor)
    let data = Data(bytes: bytes, count: byteCount)
    let rank = TfLiteTensorNumDims(cTensor)
    let dimensions = (0..<rank).map { Int(TfLiteTensorDim(cTensor, $0)) }
    let shape = Tensor.Shape(dimensions)
    let cQuantizationParams = TfLiteTensorQuantizationParams(cTensor)
    let scale = cQuantizationParams.scale
    let zeroPoint = Int(cQuantizationParams.zero_point)
    var quantizationParameters: QuantizationParameters? = nil
    if scale != 0.0 {
      quantizationParameters = QuantizationParameters(scale: scale, zeroPoint: zeroPoint)
    }
    let tensor = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    return tensor
  }
}


Interpreter

import Foundation
import TensorFlowLiteC
#if os(Linux)
  import SwiftGlibc
#else
  import Darwin
#endif
/// A TensorFlow Lite interpreter that performs inference from a given model.
///
/// - Note: Interpreter instances are *not* thread-safe.
public final class Interpreter {
  /// The configuration options for the `Interpreter`.
  public let options: Options?
  /// An `Array` of `Delegate`s for the `Interpreter` to use to perform graph operations.
  public let delegates: [Delegate]?
  /// The total number of input `Tensor`s associated with the model.
  public var inputTensorCount: Int {
    return Int(TfLiteInterpreterGetInputTensorCount(cInterpreter))
  }
  /// The total number of output `Tensor`s associated with the model.
  public var outputTensorCount: Int {
    return Int(TfLiteInterpreterGetOutputTensorCount(cInterpreter))
  }
  /// An ordered list of SignatureDef exported method names available in the model.
  public var signatureKeys: [String] {
    guard let signatureKeys = _signatureKeys else {
      let signatureCount = Int(TfLiteInterpreterGetSignatureCount(self.cInterpreter))
      let keys: [String] = (0..<signatureCount).map {
        guard
          let signatureNameCString = TfLiteInterpreterGetSignatureKey(
            self.cInterpreter, Int32($0))
        else {
          return ""
        }
        return String(cString: signatureNameCString)
      }
      _signatureKeys = keys
      return keys
    }
    return signatureKeys
  }
  /// The `TfLiteInterpreter` C pointer type represented as an `UnsafePointer<TfLiteInterpreter>`.
  internal typealias CInterpreter = OpaquePointer
  /// The underlying `TfLiteInterpreter` C pointer.
  internal var cInterpreter: CInterpreter?
  /// The underlying `TfLiteDelegate` C pointer for XNNPACK delegate.
  private var cXNNPackDelegate: Delegate.CDelegate?
  /// An ordered list of SignatureDef exported method names available in the model.
  private var _signatureKeys: [String]? = nil
  /// Creates a new instance with the given values.
  ///
  /// - Parameters:
  ///   - modelPath: The local file path to a TensorFlow Lite model.
  ///   - options: Configurations for the `Interpreter`. The default is `nil` indicating that the
  ///       `Interpreter` will determine the configuration options.
  ///   - delegate: `Array` of `Delegate`s for the `Interpreter` to use to peform graph operations.
  ///       The default is `nil`.
  /// - Throws: An error if the model could not be loaded or the interpreter could not be created.
  public init(modelPath: String, options: Options? = nil, delegates: [Delegate]? = nil) throws {
    guard let model = Model(filePath: modelPath) else { throw InterpreterError.failedToLoadModel }
    guard let cInterpreterOptions = TfLiteInterpreterOptionsCreate() else {
      throw InterpreterError.failedToCreateInterpreter
    }
    defer { TfLiteInterpreterOptionsDelete(cInterpreterOptions) }
    self.options = options
    self.delegates = delegates
    options.map {
      if let threadCount = $0.threadCount, threadCount > 0 {
        TfLiteInterpreterOptionsSetNumThreads(cInterpreterOptions, Int32(threadCount))
      }
      TfLiteInterpreterOptionsSetErrorReporter(
        cInterpreterOptions,
        { (_, format, args) -> Void in
          // Workaround for optionality differences for x86_64 (non-optional) and arm64 (optional).
          let optionalArgs: CVaListPointer? = args
          guard let cFormat = format,
            let arguments = optionalArgs,
            let message = String(cFormat: cFormat, arguments: arguments)
          else {
            return
          }
          print(String(describing: InterpreterError.tensorFlowLiteError(message)))
        },
        nil
      )
    }
    delegates?.forEach { TfLiteInterpreterOptionsAddDelegate(cInterpreterOptions, $0.cDelegate) }
    // Configure the XNNPack delegate after the other delegates explicitly added by the user.
    options.map {
      if $0.isXNNPackEnabled {
        configureXNNPack(options: $0, cInterpreterOptions: cInterpreterOptions)
      }
    }
    guard let cInterpreter = TfLiteInterpreterCreate(model.cModel, cInterpreterOptions) else {
      throw InterpreterError.failedToCreateInterpreter
    }
    self.cInterpreter = cInterpreter
  }
  deinit {
    TfLiteInterpreterDelete(cInterpreter)
    TfLiteXNNPackDelegateDelete(cXNNPackDelegate)
  }
  /// Invokes the interpreter to perform inference from the loaded graph.
  ///
  /// - Throws: An error if the model was not ready because the tensors were not allocated.
  public func invoke() throws {
    guard TfLiteInterpreterInvoke(cInterpreter) == kTfLiteOk else {
      throw InterpreterError.allocateTensorsRequired
    }
  }
  /// Returns the input `Tensor` at the given index.
  ///
  /// - Parameters:
  ///   - index: The index for the input `Tensor`.
  /// - Throws: An error if the index is invalid or the tensors have not been allocated.
  /// - Returns: The input `Tensor` at the given index.
  public func input(at index: Int) throws -> Tensor {
    let maxIndex = inputTensorCount - 1
    guard case 0...maxIndex = index else {
      throw InterpreterError.invalidTensorIndex(index: index, maxIndex: maxIndex)
    }
    guard let cTensor = TfLiteInterpreterGetInputTensor(cInterpreter, Int32(index)),
      let bytes = TfLiteTensorData(cTensor),
      let nameCString = TfLiteTensorName(cTensor)
    else {
      throw InterpreterError.allocateTensorsRequired
    }
    guard let dataType = Tensor.DataType(type: TfLiteTensorType(cTensor)) else {
      throw InterpreterError.invalidTensorDataType
    }
    let name = String(cString: nameCString)
    let rank = TfLiteTensorNumDims(cTensor)
    let dimensions = (0..<rank).map { Int(TfLiteTensorDim(cTensor, $0)) }
    let shape = Tensor.Shape(dimensions)
    let byteCount = TfLiteTensorByteSize(cTensor)
    let data = Data(bytes: bytes, count: byteCount)
    let cQuantizationParams = TfLiteTensorQuantizationParams(cTensor)
    let scale = cQuantizationParams.scale
    let zeroPoint = Int(cQuantizationParams.zero_point)
    var quantizationParameters: QuantizationParameters? = nil
    if scale != 0.0 {
      quantizationParameters = QuantizationParameters(scale: scale, zeroPoint: zeroPoint)
    }
    let tensor = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    return tensor
  }
  /// Returns the output `Tensor` at the given index.
  ///
  /// - Parameters:
  ///   - index: The index for the output `Tensor`.
  /// - Throws: An error if the index is invalid, tensors haven't been allocated, or interpreter
  ///     has not been invoked for models that dynamically compute output tensors based on the
  ///     values of its input tensors.
  /// - Returns: The output `Tensor` at the given index.
  public func output(at index: Int) throws -> Tensor {
    let maxIndex = outputTensorCount - 1
    guard case 0...maxIndex = index else {
      throw InterpreterError.invalidTensorIndex(index: index, maxIndex: maxIndex)
    }
    guard let cTensor = TfLiteInterpreterGetOutputTensor(cInterpreter, Int32(index)),
      let bytes = TfLiteTensorData(cTensor),
      let nameCString = TfLiteTensorName(cTensor)
    else {
      throw InterpreterError.invokeInterpreterRequired
    }
    guard let dataType = Tensor.DataType(type: TfLiteTensorType(cTensor)) else {
      throw InterpreterError.invalidTensorDataType
    }
    let name = String(cString: nameCString)
    let rank = TfLiteTensorNumDims(cTensor)
    let dimensions = (0..<rank).map { Int(TfLiteTensorDim(cTensor, $0)) }
    let shape = Tensor.Shape(dimensions)
    let byteCount = TfLiteTensorByteSize(cTensor)
    let data = Data(bytes: bytes, count: byteCount)
    let cQuantizationParams = TfLiteTensorQuantizationParams(cTensor)
    let scale = cQuantizationParams.scale
    let zeroPoint = Int(cQuantizationParams.zero_point)
    var quantizationParameters: QuantizationParameters? = nil
    if scale != 0.0 {
      quantizationParameters = QuantizationParameters(scale: scale, zeroPoint: zeroPoint)
    }
    let tensor = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    return tensor
  }
  /// Resizes the input `Tensor` at the given index to the specified `Tensor.Shape`.
  ///
  /// - Note: After resizing an input tensor, the client **must** explicitly call
  ///     `allocateTensors()` before attempting to access the resized tensor data or invoking the
  ///     interpreter to perform inference.
  /// - Parameters:
  ///   - index: The index for the input `Tensor`.
  ///   - shape: The shape to resize the input `Tensor` to.
  /// - Throws: An error if the input tensor at the given index could not be resized.
  public func resizeInput(at index: Int, to shape: Tensor.Shape) throws {
    let maxIndex = inputTensorCount - 1
    guard case 0...maxIndex = index else {
      throw InterpreterError.invalidTensorIndex(index: index, maxIndex: maxIndex)
    }
    guard
      TfLiteInterpreterResizeInputTensor(
        cInterpreter,
        Int32(index),
        shape.int32Dimensions,
        Int32(shape.rank)
      ) == kTfLiteOk
    else {
      throw InterpreterError.failedToResizeInputTensor(index: index)
    }
  }
  public func copy(_ data: Data, toInputAt index: Int) throws -> Tensor {
    let maxIndex = inputTensorCount - 1
    guard case 0...maxIndex = index else {
      throw InterpreterError.invalidTensorIndex(index: index, maxIndex: maxIndex)
    }
    guard let cTensor = TfLiteInterpreterGetInputTensor(cInterpreter, Int32(index)) else {
      throw InterpreterError.allocateTensorsRequired
    }
    let byteCount = TfLiteTensorByteSize(cTensor)
    guard data.count == byteCount else {
      throw InterpreterError.invalidTensorDataCount(provided: data.count, required: byteCount)
    }
    #if swift(>=5.0)
      let status = data.withUnsafeBytes {
        TfLiteTensorCopyFromBuffer(cTensor, $0.baseAddress, data.count)
      }
    #else
      let status = data.withUnsafeBytes { TfLiteTensorCopyFromBuffer(cTensor, $0, data.count) }
    #endif  // swift(>=5.0)
    guard status == kTfLiteOk else { throw InterpreterError.failedToCopyDataToInputTensor }
    return try input(at: index)
  }
  /// Allocates memory for all input `Tensor`s based on their `Tensor.Shape`s.
  ///
  /// - Note: This is a relatively expensive operation and should only be called after creating the
  ///     interpreter and resizing any input tensors.
  /// - Throws: An error if memory could not be allocated for the input tensors.
  public func allocateTensors() throws {
    guard TfLiteInterpreterAllocateTensors(cInterpreter) == kTfLiteOk else {
      throw InterpreterError.failedToAllocateTensors
    }
  }
  /// Returns a new signature runner instance for the signature with the given key in the model.
  ///
  /// - Parameters:
  ///   - key: The signature key.
  /// - Throws: `SignatureRunnerError` if signature runner creation fails.
  /// - Returns: A new signature runner instance for the signature with the given key.
  public func signatureRunner(with key: String) throws -> SignatureRunner {
    guard signatureKeys.contains(key) else {
      throw SignatureRunnerError.failedToCreateSignatureRunner(signatureKey: key)
    }
    return try SignatureRunner.init(interpreter: self, signatureKey: key)
  }
  // MARK: - Private
  private func configureXNNPack(options: Options, cInterpreterOptions: OpaquePointer) {
    var cXNNPackOptions = TfLiteXNNPackDelegateOptionsDefault()
    if let threadCount = options.threadCount, threadCount > 0 {
      cXNNPackOptions.num_threads = Int32(threadCount)
    }
    cXNNPackDelegate = TfLiteXNNPackDelegateCreate(&cXNNPackOptions)
    TfLiteInterpreterOptionsAddDelegate(cInterpreterOptions, cXNNPackDelegate)
  }
}
extension Interpreter {
  /// Options for configuring the `Interpreter`.
  public struct Options: Equatable, Hashable {
    /// The maximum number of CPU threads that the interpreter should run on. The default is `nil`
    /// indicating that the `Interpreter` will decide the number of threads to use.
    public var threadCount: Int? = nil
    /// Indicates whether an optimized set of floating point CPU kernels, provided by XNNPACK, is
    /// enabled.
    ///
    /// - Experiment:
    /// Enabling this flag will enable use of a new, highly optimized set of CPU kernels provided
    /// via the XNNPACK delegate. Currently, this is restricted to a subset of floating point
    /// operations. Eventually, we plan to enable this by default, as it can provide significant
    /// performance benefits for many classes of floating point models. See
    /// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/delegates/xnnpack/README.md
    /// for more details.
    ///
    /// - Important:
    /// Things to keep in mind when enabling this flag:
    ///
    ///     * Startup time and resize time may increase.
    ///     * Baseline memory consumption may increase.
    ///     * Compatibility with other delegates (e.g., GPU) has not been fully validated.
    ///     * Quantized models will not see any benefit.
    ///
    /// - Warning: This is an experimental interface that is subject to change.
    public var isXNNPackEnabled: Bool = false
    /// Creates a new instance with the default values.
    public init() {}
  }
}
/// A type alias for `Interpreter.Options` to support backwards compatibility with the deprecated
/// `InterpreterOptions` struct.
public typealias InterpreterOptions = Interpreter.Options
extension String {
  /// Returns a new `String` initialized by using the given format C array as a template into which
  /// the remaining argument values are substituted according to the user’s default locale.
  ///
  /// - Note: Returns `nil` if a new `String` could not be constructed from the given values.
  /// - Parameters:
  ///   - cFormat: The format C array as a template for substituting values.
  ///   - arguments: A C pointer to a `va_list` of arguments to substitute into `cFormat`.
  init?(cFormat: UnsafePointer<CChar>, arguments: CVaListPointer) {
    #if os(Linux)
      let length = Int(vsnprintf(nil, 0, cFormat, arguments) + 1)  // null terminator
      guard length > 0 else { return nil }
      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: length)
      defer {
        buffer.deallocate()
      }
      guard vsnprintf(buffer, length, cFormat, arguments) == length - 1 else { return nil }
      self.init(validatingUTF8: buffer)
    #else
      var buffer: UnsafeMutablePointer<CChar>?
      guard vasprintf(&buffer, cFormat, arguments) != 0, let cString = buffer else { return nil }
      self.init(validatingUTF8: cString)
    #endif
  }
}


Tensor

import Foundation
import TensorFlowLiteC
/// An input or output tensor in a TensorFlow Lite graph.
public struct Tensor: Equatable, Hashable {
  /// The name of the `Tensor`.
  public let name: String
  /// The data type of the `Tensor`.
  public let dataType: DataType
  /// The shape of the `Tensor`.
  public let shape: Shape
  /// The data of the `Tensor`. The data is created with copied memory content. See creating data
  /// from raw memory at https://developer.apple.com/documentation/foundation/data.
  public let data: Data
  /// The quantization parameters for the `Tensor` if using a quantized model.
  public let quantizationParameters: QuantizationParameters?
  /// Creates a new input or output `Tensor` instance.
  ///
  /// - Parameters:
  ///   - name: The name of the `Tensor`.
  ///   - dataType: The data type of the `Tensor`.
  ///   - shape: The shape of the `Tensor`.
  ///   - data: The data in the input `Tensor`.
  ///   - quantizationParameters Parameters for the `Tensor` if using a quantized model. The default
  ///       is `nil`.
  init(
    name: String,
    dataType: DataType,
    shape: Shape,
    data: Data,
    quantizationParameters: QuantizationParameters? = nil
  ) {
    self.name = name
    self.dataType = dataType
    self.shape = shape
    self.data = data
    self.quantizationParameters = quantizationParameters
  }
}
extension Tensor {
  /// The supported `Tensor` data types.
  public enum DataType: Equatable, Hashable {
    /// A boolean.
    case bool
    /// An 8-bit unsigned integer.
    case uInt8
    /// A 16-bit signed integer.
    case int16
    /// A 32-bit signed integer.
    case int32
    /// A 64-bit signed integer.
    case int64
    /// A 16-bit half precision floating point.
    case float16
    /// A 32-bit single precision floating point.
    case float32
    /// A 64-bit double precision floating point.
    case float64
    /// Creates a new instance from the given `TfLiteType` or `nil` if the data type is unsupported
    /// or could not be determined because there was an error.
    ///
    /// - Parameter type: A data type for a tensor.
    init?(type: TfLiteType) {
      switch type {
      case kTfLiteBool:
        self = .bool
      case kTfLiteUInt8:
        self = .uInt8
      case kTfLiteInt16:
        self = .int16
      case kTfLiteInt32:
        self = .int32
      case kTfLiteInt64:
        self = .int64
      case kTfLiteFloat16:
        self = .float16
      case kTfLiteFloat32:
        self = .float32
      case kTfLiteFloat64:
        self = .float64
      case kTfLiteNoType:
        fallthrough
      default:
        return nil
      }
    }
  }
}
extension Tensor {
  /// The shape of a `Tensor`.
  public struct Shape: Equatable, Hashable {
    /// The number of dimensions of the `Tensor`.
    public let rank: Int
    /// An array of dimensions for the `Tensor`.
    public let dimensions: [Int]
    /// An array of `Int32` dimensions for the `Tensor`.
    var int32Dimensions: [Int32] { return dimensions.map(Int32.init) }
    /// Creates a new instance with the given array of dimensions.
    ///
    /// - Parameters:
    ///   - dimensions: Dimensions for the `Tensor`.
    public init(_ dimensions: [Int]) {
      self.rank = dimensions.count
      self.dimensions = dimensions
    }
    /// Creates a new instance with the given elements representing the dimensions.
    ///
    /// - Parameters:
    ///   - elements: Dimensions for the `Tensor`.
    public init(_ elements: Int...) {
      self.init(elements)
    }
  }
}
extension Tensor.Shape: ExpressibleByArrayLiteral {
  /// Creates a new instance with the given array literal representing the dimensions.
  ///
  /// - Parameters:
  ///   - arrayLiteral: Dimensions for the `Tensor`.
  public init(arrayLiteral: Int...) {
    self.init(arrayLiteral)
  }
}
/// A tensor's function level purpose: input or output.
internal enum TensorType: String {
  case input
  case output
}


MetalDelegateTests

class MetalDelegateTests: XCTestCase {
  func testInitDefaultGPUDelegateOptions() {
    let delegate = MetalDelegate()
    XCTAssertFalse(delegate.options.isPrecisionLossAllowed)
    XCTAssertEqual(delegate.options.waitType, .passive)
  }
  func testInitWithCustomGPUDelegateOptions() {
    var options = MetalDelegate.Options()
    options.isPrecisionLossAllowed = true
    options.waitType = .active
    let delegate = MetalDelegate(options: options)
    XCTAssertTrue(delegate.options.isPrecisionLossAllowed)
    XCTAssertEqual(delegate.options.waitType, .active)
  }
  func testInitInterpreterWithDelegate() throws {
    // If metal device is not available, skip.
    if MTLCreateSystemDefaultDevice() == nil {
      return
    }
    let metalDelegate = MetalDelegate()
    let interpreter = try Interpreter(modelPath: MultiAddModel.path, delegates: [metalDelegate])
    XCTAssertEqual(interpreter.delegates?.count, 1)
    XCTAssertNil(interpreter.options)
  }
  func testInitInterpreterWithOptionsAndDelegate() throws {
    // If metal device is not available, skip.
    if MTLCreateSystemDefaultDevice() == nil {
      return
    }
    var options = Interpreter.Options()
    options.threadCount = 1
    let metalDelegate = MetalDelegate()
    let interpreter = try Interpreter(
      modelPath: MultiAddModel.path,
      options: options,
      delegates: [metalDelegate]
    )
    XCTAssertNotNil(interpreter.options)
    XCTAssertEqual(interpreter.delegates?.count, 1)
  }
}
class MetalDelegateOptionsTests: XCTestCase {
  func testInitWithDefaultValues() {
    let options = MetalDelegate.Options()
    XCTAssertFalse(options.isPrecisionLossAllowed)
    XCTAssertEqual(options.waitType, .passive)
  }
  func testInitWithCustomValues() {
    var options = MetalDelegate.Options()
    options.isPrecisionLossAllowed = true
    options.waitType = .active
    XCTAssertTrue(options.isPrecisionLossAllowed)
    XCTAssertEqual(options.waitType, .active)
  }
  func testEquatable() {
    var options1 = MetalDelegate.Options()
    var options2 = MetalDelegate.Options()
    XCTAssertEqual(options1, options2)
    options1.isPrecisionLossAllowed = true
    options2.isPrecisionLossAllowed = true
    XCTAssertEqual(options1, options2)
    options1.waitType = .none
    options2.waitType = .none
    XCTAssertEqual(options1, options2)
    options2.isPrecisionLossAllowed = false
    XCTAssertNotEqual(options1, options2)
    options1.isPrecisionLossAllowed = false
    options1.waitType = .aggressive
    XCTAssertNotEqual(options1, options2)
  }
}
/// Values for the `multi_add.bin` model.
enum MultiAddModel {
  static let info = (name: "multi_add", extension: "bin")
  static var path: String = {
    let bundle = Bundle(for: MetalDelegateTests.self)
    guard let path = bundle.path(forResource: info.name, ofType: info.extension) else { return "" }
    return path
  }()
}


QuantizationParametersTests

class QuantizationParametersTests: XCTestCase {
  func testInitWithCustomValues() {
    let parameters = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    XCTAssertEqual(parameters.scale, 0.5)
    XCTAssertEqual(parameters.zeroPoint, 1)
  }
  func testEquatable() {
    let parameters1 = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    let parameters2 = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    XCTAssertEqual(parameters1, parameters2)
    let parameters3 = QuantizationParameters(scale: 0.4, zeroPoint: 1)
    XCTAssertNotEqual(parameters1, parameters3)
    XCTAssertNotEqual(parameters2, parameters3)
  }
}


ModelTests

class ModelTests: XCTestCase {
  var modelPath: String!
  override func setUp() {
    super.setUp()
    let bundle = Bundle(for: type(of: self))
    guard let modelPath = bundle.path(
      forResource: Constant.modelInfo.name,
      ofType: Constant.modelInfo.extension
    ) else {
      XCTFail("Failed to get the model file path.")
      return
    }
    self.modelPath = modelPath
  }
  override func tearDown() {
    modelPath = nil
    super.tearDown()
  }
  func testInitWithFilePath() {
    XCTAssertNotNil(Model(filePath: modelPath))
  }
  func testInitWithEmptyFilePath_FailsInitialization() {
    XCTAssertNil(Model(filePath: ""))
  }
  func testInitWithInvalidFilePath_FailsInitialization() {
    XCTAssertNil(Model(filePath: "invalid/path"))
  }
}
// MARK: - Constants
private enum Constant {
  static let modelInfo = (name: "add", extension: "bin")
}


InterpreterTests

class InterpreterTests: XCTestCase {
  var interpreter: Interpreter!
  override func setUp() {
    super.setUp()
    interpreter = try! Interpreter(modelPath: AddModel.path)
  }
  override func tearDown() {
    interpreter = nil
    super.tearDown()
  }
  func testInit_ValidModelPath() {
    XCTAssertNoThrow(try Interpreter(modelPath: AddModel.path))
  }
  func testInit_InvalidModelPath_ThrowsFailedToLoadModel() {
    XCTAssertThrowsError(try Interpreter(modelPath: "/invalid/path")) { error in
      self.assertEqualErrors(actual: error, expected: .failedToLoadModel)
    }
  }
  func testInitWithOptions() throws {
    var options = Interpreter.Options()
    options.threadCount = 2
    let interpreter = try Interpreter(modelPath: AddQuantizedModel.path, options: options)
    XCTAssertNotNil(interpreter.options)
    XCTAssertNil(interpreter.delegates)
  }
  func testInputTensorCount() {
    XCTAssertEqual(interpreter.inputTensorCount, AddModel.inputTensorCount)
  }
  func testOutputTensorCount() {
    XCTAssertEqual(interpreter.outputTensorCount, AddModel.outputTensorCount)
  }
  func testInvoke() throws {
    try interpreter.allocateTensors()
    XCTAssertNoThrow(try interpreter.invoke())
  }
  func testInvoke_ThrowsAllocateTensorsRequired_ModelNotReady() {
    XCTAssertThrowsError(try interpreter.invoke()) { error in
      self.assertEqualErrors(actual: error, expected: .allocateTensorsRequired)
    }
  }
  func testInputTensorAtIndex() throws {
    try setUpAddModelInputTensor()
    let inputTensor = try interpreter.input(at: AddModel.validIndex)
    XCTAssertEqual(inputTensor, AddModel.inputTensor)
  }
  func testInputTensorAtIndex_QuantizedModel() throws {
    interpreter = try Interpreter(modelPath: AddQuantizedModel.path)
    try setUpAddQuantizedModelInputTensor()
    let inputTensor = try interpreter.input(at: AddQuantizedModel.inputOutputIndex)
    XCTAssertEqual(inputTensor, AddQuantizedModel.inputTensor)
  }
  func testInputTensorAtIndex_ThrowsInvalidIndex() throws {
    try interpreter.allocateTensors()
    XCTAssertThrowsError(try interpreter.input(at: AddModel.invalidIndex)) { error in
      let maxIndex = AddModel.inputTensorCount - 1
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorIndex(index: AddModel.invalidIndex, maxIndex: maxIndex)
      )
    }
  }
  func testInputTensorAtIndex_ThrowsAllocateTensorsRequired() {
    XCTAssertThrowsError(try interpreter.input(at: AddModel.validIndex)) { error in
      self.assertEqualErrors(actual: error, expected: .allocateTensorsRequired)
    }
  }
  func testOutputTensorAtIndex() throws {
    try setUpAddModelInputTensor()
    try interpreter.invoke()
    let outputTensor = try interpreter.output(at: AddModel.validIndex)
    XCTAssertEqual(outputTensor, AddModel.outputTensor)
    let expectedResults = [Float32](unsafeData: outputTensor.data)
    XCTAssertEqual(expectedResults, AddModel.results)
  }
  func testOutputTensorAtIndex_QuantizedModel() throws {
    interpreter = try Interpreter(modelPath: AddQuantizedModel.path)
    try setUpAddQuantizedModelInputTensor()
    try interpreter.invoke()
    let outputTensor = try interpreter.output(at: AddQuantizedModel.inputOutputIndex)
    XCTAssertEqual(outputTensor, AddQuantizedModel.outputTensor)
    let expectedResults = [UInt8](outputTensor.data)
    XCTAssertEqual(expectedResults, AddQuantizedModel.results)
  }
  func testOutputTensorAtIndex_ThrowsInvalidIndex() throws {
    try interpreter.allocateTensors()
    try interpreter.invoke()
    XCTAssertThrowsError(try interpreter.output(at: AddModel.invalidIndex)) { error in
      let maxIndex = AddModel.outputTensorCount - 1
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorIndex(index: AddModel.invalidIndex, maxIndex: maxIndex)
      )
    }
  }
  func testOutputTensorAtIndex_ThrowsInvokeInterpreterRequired() {
    XCTAssertThrowsError(try interpreter.output(at: AddModel.validIndex)) { error in
      self.assertEqualErrors(actual: error, expected: .invokeInterpreterRequired)
    }
  }
  func testResizeInputTensorAtIndexToShape() {
    XCTAssertNoThrow(try interpreter.resizeInput(at: AddModel.validIndex, to: [2, 2, 3]))
    XCTAssertNoThrow(try interpreter.allocateTensors())
  }
  func testResizeInputTensorAtIndexToShape_ThrowsInvalidIndex() {
    XCTAssertThrowsError(
      try interpreter.resizeInput(
        at: AddModel.invalidIndex,
        to: [2, 2, 3]
      )
    ) { error in
      let maxIndex = AddModel.inputTensorCount - 1
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorIndex(index: AddModel.invalidIndex, maxIndex: maxIndex)
      )
    }
  }
  func testCopyDataToInputTensorAtIndex() throws {
    try interpreter.resizeInput(at: AddModel.validIndex, to: AddModel.shape)
    try interpreter.allocateTensors()
    let inputTensor = try interpreter.copy(AddModel.inputData, toInputAt: AddModel.validIndex)
    XCTAssertEqual(inputTensor.data, AddModel.inputData)
  }
  func testCopyDataToInputTensorAtIndex_ThrowsInvalidIndex() {
    XCTAssertThrowsError(
      try interpreter.copy(
        AddModel.inputData,
        toInputAt: AddModel.invalidIndex
      )
    ) { error in
      let maxIndex = AddModel.inputTensorCount - 1
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorIndex(index: AddModel.invalidIndex, maxIndex: maxIndex)
      )
    }
  }
  func testCopyDataToInputTensorAtIndex_ThrowsInvalidDataCount() throws {
    try interpreter.resizeInput(at: AddModel.validIndex, to: AddModel.shape)
    try interpreter.allocateTensors()
    let invalidData = Data(count: AddModel.dataCount - 1)
    XCTAssertThrowsError(
      try interpreter.copy(
        invalidData,
        toInputAt: AddModel.validIndex
      )
    ) { error in
      self.assertEqualErrors(
        actual: error,
        expected: .invalidTensorDataCount(provided: invalidData.count, required: AddModel.dataCount)
      )
    }
  }
  func testAllocateTensors() {
    XCTAssertNoThrow(try interpreter.allocateTensors())
  }
  // MARK: - Private
  private func setUpAddModelInputTensor() throws {
    precondition(interpreter != nil)
    try interpreter.resizeInput(at: AddModel.validIndex, to: AddModel.shape)
    try interpreter.allocateTensors()
    try interpreter.copy(AddModel.inputData, toInputAt: AddModel.validIndex)
  }
  private func setUpAddQuantizedModelInputTensor() throws {
    precondition(interpreter != nil)
    try interpreter.resizeInput(at: AddQuantizedModel.inputOutputIndex, to: AddQuantizedModel.shape)
    try interpreter.allocateTensors()
    try interpreter.copy(AddQuantizedModel.inputData, toInputAt: AddQuantizedModel.inputOutputIndex)
  }
  private func assertEqualErrors(actual: Error, expected: InterpreterError) {
    guard let actual = actual as? InterpreterError else {
      XCTFail("Actual error should be of type InterpreterError.")
      return
    }
    XCTAssertEqual(actual, expected)
  }
}
class InterpreterOptionsTests: XCTestCase {
  func testInitWithDefaultValues() {
    let options = Interpreter.Options()
    XCTAssertNil(options.threadCount)
    XCTAssertFalse(options.isXNNPackEnabled)
  }
  func testInitWithCustomValues() {
    var options = Interpreter.Options()
    options.threadCount = 2
    XCTAssertEqual(options.threadCount, 2)
    options.isXNNPackEnabled = false
    XCTAssertFalse(options.isXNNPackEnabled)
    options.isXNNPackEnabled = true
    XCTAssertTrue(options.isXNNPackEnabled)
  }
  func testEquatable() {
    var options1 = Interpreter.Options()
    var options2 = Interpreter.Options()
    XCTAssertEqual(options1, options2)
    options1.threadCount = 2
    options2.threadCount = 2
    XCTAssertEqual(options1, options2)
    options2.threadCount = 3
    XCTAssertNotEqual(options1, options2)
    options2.threadCount = 2
    XCTAssertEqual(options1, options2)
    options2.isXNNPackEnabled = true
    XCTAssertNotEqual(options1, options2)
    options1.isXNNPackEnabled = true
    XCTAssertEqual(options1, options2)
  }
}
// MARK: - Constants
/// Values for the `add.bin` model.
enum AddModel {
  static let info = (name: "add", extension: "bin")
  static let inputTensorCount = 1
  static let outputTensorCount = 1
  static let invalidIndex = 1
  static let validIndex = 0
  static let shape: Tensor.Shape = [2]
  static let dataCount = inputData.count
  static let results = [Float32(3.0), Float32(9.0)]
  static let inputTensor = Tensor(
    name: "input",
    dataType: .float32,
    shape: shape,
    data: inputData
  )
  static let outputTensor = Tensor(
    name: "output",
    dataType: .float32,
    shape: shape,
    data: outputData
  )
  static var path: String = {
    let bundle = Bundle(for: InterpreterTests.self)
    guard let path = bundle.path(forResource: info.name, ofType: info.extension) else { return "" }
    return path
  }()
}
/// Values for the `add_quantized.bin` model.
enum AddQuantizedModel {
  static let info = (name: "add_quantized", extension: "bin")
  static let inputOutputIndex = 0
  static let shape: Tensor.Shape = [2]
  static let inputData = Data([1, 3])
  static let outputData = Data([3, 9])
  static let quantizationParameters = QuantizationParameters(scale: 0.003922, zeroPoint: 0)
  static let results: [UInt8] = [3, 9]
  static let inputTensor = Tensor(
    name: "input",
    dataType: .uInt8,
    shape: shape,
    data: inputData,
    quantizationParameters: quantizationParameters
  )
  static let outputTensor = Tensor(
    name: "output",
    dataType: .uInt8,
    shape: shape,
    data: outputData,
    quantizationParameters: quantizationParameters
  )
  static var path: String = {
    let bundle = Bundle(for: InterpreterTests.self)
    guard let path = bundle.path(forResource: info.name, ofType: info.extension) else { return "" }
    return path
  }()
}
// MARK: - Extensions
extension Array {
  /// Creates a new array from the bytes of the given unsafe data.
  ///
  /// - Warning: The array's `Element` type must be trivial in that it can be copied bit for bit
  ///     the `unsafeData`'s buffer to a new array returns an unsafe copy.
  /// - Note: Returns `nil` if `unsafeData.count` is not a multiple of
  ///     `MemoryLayout<Element>.stride`.
  /// - Parameter unsafeData: The data containing the bytes to turn into an array.
  init?(unsafeData: Data) {
    guard unsafeData.count % MemoryLayout<Element>.stride == 0 else { return nil }
    #if swift(>=5.0)
      self = unsafeData.withUnsafeBytes { .init($0.bindMemory(to: Element.self)) }
    #else
      self = unsafeData.withUnsafeBytes {
        .init(
          UnsafeBufferPointer<Element>(
            start: $0,
            count: unsafeData.count / MemoryLayout<Element>.stride
          ))
      }
    #endif  // swift(>=5.0)
  }
}
extension Data {
    self = array.withUnsafeBufferPointer(Data.init)
  }
}


TensorFlowLiteTests

class TensorFlowLiteTests: XCTestCase {
  func testRuntime_Version() {
    #if swift(>=5.0)
    let pattern = #"^(\d+)\.(\d+)\.(\d+)([+-][-.0-9A-Za-z]+)?$"#
    #else
    let pattern = "^(\\d+)\\.(\\d+)\\.(\\d+)([+-][-.0-9A-Za-z]+)?$"
    #endif  // swift(>=5.0)
    XCTAssertNotNil(TensorFlowLite.Runtime.version.range(of: pattern, options: .regularExpression))
  }
}


TensorTests

class TensorTests: XCTestCase {
  func testInit() {
    let name = "InputTensor"
    let dataType: Tensor.DataType = .uInt8
    let shape = Tensor.Shape(Constant.dimensions)
    guard let data = name.data(using: .utf8) else { XCTFail("Data should not be nil."); return }
    let quantizationParameters = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    let inputTensor = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    XCTAssertEqual(inputTensor.name, name)
    XCTAssertEqual(inputTensor.dataType, dataType)
    XCTAssertEqual(inputTensor.shape, shape)
    XCTAssertEqual(inputTensor.data, data)
    XCTAssertEqual(inputTensor.quantizationParameters, quantizationParameters)
  }
  func testEquatable() {
    let name = "Tensor"
    let dataType: Tensor.DataType = .uInt8
    let shape = Tensor.Shape(Constant.dimensions)
    guard let data = name.data(using: .utf8) else { XCTFail("Data should not be nil."); return }
    let quantizationParameters = QuantizationParameters(scale: 0.5, zeroPoint: 1)
    let tensor1 = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    var tensor2 = Tensor(
      name: name,
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    XCTAssertEqual(tensor1, tensor2)
    tensor2 = Tensor(
      name: "Tensor2",
      dataType: dataType,
      shape: shape,
      data: data,
      quantizationParameters: quantizationParameters
    )
    XCTAssertNotEqual(tensor1, tensor2)
  }
}
class TensorShapeTests: XCTestCase {
  func testInitWithArray() {
    let shape = Tensor.Shape(Constant.dimensions)
    XCTAssertEqual(shape.rank, Constant.dimensions.count)
    XCTAssertEqual(shape.dimensions, Constant.dimensions)
  }
  func testInitWithElements() {
    let shape = Tensor.Shape(2, 2, 3)
    XCTAssertEqual(shape.rank, Constant.dimensions.count)
    XCTAssertEqual(shape.dimensions, Constant.dimensions)
  }
  func testInitWithArrayLiteral() {
    let shape: Tensor.Shape = [2, 2, 3]
    XCTAssertEqual(shape.rank, Constant.dimensions.count)
    XCTAssertEqual(shape.dimensions, Constant.dimensions)
  }
  func testEquatable() {
    let shape1 = Tensor.Shape(2, 2, 3)
    var shape2: Tensor.Shape = [2, 2, 3]
    XCTAssertEqual(shape1, shape2)
    shape2 = [2, 2, 4]
    XCTAssertNotEqual(shape1, shape2)
  }
}
// MARK: - Constants
private enum Constant {
  /// Array of 2 arrays of 2 arrays of 3 numbers: [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]].
  static let dimensions = [2, 2, 3]
}


SignatureRunnerTest

class SignatureRunnerTest: XCTestCase {
  func testSignatureKeys() throws {
    let interpreter = try Interpreter(modelPath: MultiSignaturesModel.path)
    XCTAssertEqual(interpreter.signatureKeys, MultiSignaturesModel.signatureKeys)
    XCTAssertNotNil(try interpreter.signatureRunner(with: MultiSignaturesModel.AddSignature.key))
    XCTAssertThrowsError(try interpreter.signatureRunner(with: "dummy")) { error in
      self.assertEqualErrors(
        actual: error, expected: .failedToCreateSignatureRunner(signatureKey: "dummy"))
    }
  }
  func testResizeInputTensor() throws {
    let interpreter = try Interpreter(modelPath: MultiSignaturesModel.path)
    let addRunner = try interpreter.signatureRunner(with: MultiSignaturesModel.AddSignature.key)
    XCTAssertEqual(addRunner.inputs, MultiSignaturesModel.AddSignature.inputs)
    let inputTensor = try addRunner.input(named: "x")
    // Validate signature "add" input tensor "x" before resizing.
    XCTAssertEqual(inputTensor.name, MultiSignaturesModel.AddSignature.inputTensor.name)
    XCTAssertEqual(inputTensor.dataType, MultiSignaturesModel.AddSignature.inputTensor.dataType)
    XCTAssertEqual(inputTensor.shape, [1])
    // Test fail to copy data before resizing the tensor
    XCTAssertThrowsError(
      try addRunner.copy(MultiSignaturesModel.AddSignature.inputData, toInputNamed: "x")
    ) { error in
      self.assertEqualErrors(
        actual: error, expected: .invalidTensorDataCount(provided: 8, required: 4))
    }
    // Resize signature "add" input tensor "x"
    try addRunner.resizeInput(named: "x", toShape: MultiSignaturesModel.AddSignature.shape)
    try addRunner.allocateTensors()
    // Copy data to input tensor "x"
    try addRunner.copy(MultiSignaturesModel.AddSignature.inputData, toInputNamed: "x")
    XCTAssertEqual(
      try addRunner.input(named: "x"), MultiSignaturesModel.AddSignature.inputTensor)
  }
  func testResizeInputTensor_invalidTensor() throws {
    let interpreter = try Interpreter(modelPath: MultiSignaturesModel.path)
    let addRunner = try interpreter.signatureRunner(with: MultiSignaturesModel.AddSignature.key)
    // Test fail to get input tensor for a dummy input name.
    XCTAssertThrowsError(
      try addRunner.input(named: "dummy")
    ) { error in
      self.assertEqualErrors(
        actual: error, expected: .failedToGetTensor(tensorType: "input", nameInSignature: "dummy"))
    }
    // Test fail to resize dummy input tensor
    XCTAssertThrowsError(
      try addRunner.resizeInput(named: "dummy", toShape: [2])
    ) { error in
      self.assertEqualErrors(
        actual: error, expected: .failedToResizeInputTensor(inputName: "dummy"))
    }
  }
  func testInvokeWithInputs() throws {
    let interpreter = try Interpreter(modelPath: MultiSignaturesModel.path)
    let addRunner = try interpreter.signatureRunner(with: MultiSignaturesModel.AddSignature.key)
    XCTAssertEqual(addRunner.outputs, MultiSignaturesModel.AddSignature.outputs)
    // Validate signature "add" output tensor "output_0" before inference
    let outputTensor = try addRunner.output(named: "output_0")
    XCTAssertEqual(outputTensor.name, MultiSignaturesModel.AddSignature.outputTensor.name)
    XCTAssertEqual(outputTensor.dataType, MultiSignaturesModel.AddSignature.outputTensor.dataType)
    XCTAssertEqual(outputTensor.shape, [1])
    // Resize signature "add" input tensor "x"
    try addRunner.resizeInput(named: "x", toShape: MultiSignaturesModel.AddSignature.shape)
    // Invoke signature "add" with inputs.
    try addRunner.invoke(with: ["x": MultiSignaturesModel.AddSignature.inputData])
    // Validate signature "add" output tensor "output_0" after inference
    XCTAssertEqual(
      try addRunner.output(named: "output_0"), MultiSignaturesModel.AddSignature.outputTensor)
  }
  // MARK: - Private
  private func assertEqualErrors(actual: Error, expected: SignatureRunnerError) {
    guard let actual = actual as? SignatureRunnerError else {
      XCTFail("Actual error should be of type SignatureRunnerError.")
      return
    }
    XCTAssertEqual(actual, expected)
  }
}
// MARK: - Constants
/// Values for the `multi_signatures.bin` model.
enum MultiSignaturesModel {
  static let info = (name: "multi_signatures", extension: "bin")
  static let signatureKeys = [AddSignature.key, SubSignature.key]
  static var path: String = {
    let bundle = Bundle(for: SignatureRunnerTest.self)
    guard let path = bundle.path(forResource: info.name, ofType: info.extension) else { return "" }
    return path
  }()
  enum AddSignature {
    static let key = "add"
    static let inputs = ["x"]
    static let outputs = ["output_0"]
    static let shape: Tensor.Shape = [2]
    static let inputTensor = Tensor(
      name: "add_x:0",
      dataType: .float32,
      shape: shape,
      data: inputData
    )
    static let outputTensor = Tensor(
      name: "StatefulPartitionedCall:0",
      dataType: .float32,
      shape: shape,
      data: outputData
    )
  }
  enum SubSignature {
    static let key = "sub"
  }
}


ViewController

/*
 *
 *
 */
import UIKit
import RemoteTest
class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    let RemoteHost = "grpc-test.sandbox.googleapis.com"
    let request = RMTSimpleRequest()
    request.responseSize = 10
    request.fillUsername = true
    request.fillOauthScope = true
    // Example gRPC call using a generated proto client library:
    let service = RMTTestService(host: RemoteHost)
    service.unaryCall(with: request) { response, error in
      if let response = response {
        NSLog("1. Finished successfully with response:\n\(response)")
      } else {
        NSLog("1. Finished with error: \(error!)")
      }
    }
    // Same but manipulating headers:
    var RPC : GRPCProtoCall! // Needed to convince Swift to capture by reference (__block)
    RPC = service.rpcToUnaryCall(with: request) { response, error in
      if let response = response {
        NSLog("2. Finished successfully with response:\n\(response)")
      } else {
        NSLog("2. Finished with error: \(error!)")
      }
      NSLog("2. Response headers: \(String(describing: RPC.responseHeaders))")
      NSLog("2. Response trailers: \(String(describing: RPC.responseTrailers))")
    }
    // TODO(jcanizales): Revert to using subscript syntax once XCode 8 is released.
    RPC.requestHeaders["My-Header"] = "My value"
    RPC.start()
    // Same example call using the generic gRPC client library:
    let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")!
    let requestsWriter = GRXWriter(value: request.data())!
    let call = GRPCCall(host: RemoteHost, path: method.httpPath, requestsWriter: requestsWriter)!
    call.requestHeaders["My-Header"] = "My value"
    call.start(with: GRXWriteable { response, error in
      if let response = response as? Data {
        NSLog("3. Received response:\n\(try! RMTSimpleResponse(data: response))")
      } else {
        NSLog("3. Finished with error: \(error!)")
      }
      NSLog("3. Response headers: \(String(describing: call.responseHeaders))")
      NSLog("3. Response trailers: \(String(describing: call.responseTrailers))")
    })
  }
}


AppDelegate

/*
 *
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
}


s

infix operator •: AdditionPrecedence
func • (a: Int, b: Int) -> Int {
  return a * b
}
func g(a: Int) -> Int{
  return a + 1
}
let i = g(a: 1 • 2)


import Swift

var s: [Int] = [1, 2, 3, 4]

func f() {
  for i in 0..<4 {
    print(s[i])
  }
}

f()


ContentView

/*
 */
import SwiftUI
struct ContentView: View {
  let greet = "Hello Benchmarking"
  var body: some View {
    Text(greet)
  }
}
struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}


iosApp

/*
struct iOSApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}


Benchmarks

/*
 */
import Foundation
import XCTest
import AndroidXDarwinBenchmarks
class BenchmarkTest: XCTestCase {
    var testCase: TestCase? = nil
    override func setUpWithError() throws {
        testCase!.setUp()
    }
    override class var defaultTestSuite: XCTestSuite {
        let suite = XCTestSuite(forTestCaseClass: BenchmarkTest.self)
        let testCases = TestCases.shared.benchmarkTests()
        for testCase in testCases {
            let test = BenchmarkTest(selector: #selector(runBenchmark))
            test.testCase = testCase
            suite.addTest(test)
        }
        return suite
    }
        // https://masilotti.com/xctest-name-readability/
        XCTContext.runActivity(named: testCase!.testDescription()) { _ -> Void in
            // Run the actual benchmark
            let context = TestCaseContextWrapper(context: self)
            testCase?.benchmark(context: context)
        }
    }
}


Package

// swift-tools-version:5.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "zstd",
    platforms: [
        .macOS(.v10_10), .iOS(.v9), .tvOS(.v9)
    ],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "libzstd",
            targets: [ "libzstd" ])
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "libzstd",
            path: "lib",
            sources: [ "common", "compress", "decompress", "dictBuilder" ],
            publicHeadersPath: ".",
            cSettings: [
                .headerSearchPath(".")
            ])
    ],
    swiftLanguageVersions: [.v5],
    cLanguageStandard: .gnu11,
    cxxLanguageStandard: .gnucxx14
)


// swift-tools-version:5.2
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription

let package = Package(
  name: "gRPC",
  products: [
    .library(
      name: "gRPC-Core",
      targets: [
        "gRPC-Core",
      ]
    ),
    .library(
      name: "gRPC-cpp",
      targets: [
        "gRPC-cpp",
      ]
    )
  ],

  dependencies: [
    .package(
      name: "abseil",
      url: "https://github.com/firebase/abseil-cpp-SwiftPM.git",
      .revision("05d8107f2971a37e6c77245b7c4c6b0a7e97bc99")
    ),
    .package(name: "BoringSSL-GRPC",
      url: "https://github.com/firebase/boringssl-SwiftPM.git",
      .branch("7bcafa2660bc58715c39637494550d1ed7cd7229")
    ),
  ],

  targets: [
    .target(
      name: "gRPC-Core",
      dependencies: [
        .product(name:"abseil", package: "abseil"),
        .product(name:"openssl_grpc", package: "BoringSSL-GRPC"),
      ],
      path: ".",
      exclude: [
        "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc",
        "src/core/ext/filters/client_channel/xds/xds_channel.cc",
        "src/core/ext/filters/load_reporting/",
        "src/core/ext/transport/cronet/",
        "src/core/ext/upb-generated/third_party/",
        "src/core/ext/upb-generated/src/proto/grpc/auth/",
        "src/core/ext/upbdefs-generated/envoy/config/rbac/",
        "src/core/ext/upbdefs-generated/google/api/expr/",
        "src/core/ext/upbdefs-generated/src/",
        "src/core/ext/upbdefs-generated/third_party/",
        "src/core/ext/upbdefs-generated/udpa/data/",
        "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h",
        "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc",
        "src/core/lib/surface/init_unsecure.cc",
        "src/core/lib/security/authorization/",
        "src/core/plugin_registry/grpc_unsecure_plugin_registry.cc",
        "third_party/re2/re2/testing/",
        "third_party/re2/re2/fuzzing/",
        "third_party/re2/util/benchmark.cc",
        "third_party/re2/util/test.cc",
        "third_party/re2/util/fuzz.cc",
        "third_party/upb/upb/sink.c",
        "third_party/upb/upb/json_decode.c",
        "third_party/upb/upb/json_encode.c",
        "third_party/upb/upb/handlers.h",
        "third_party/upb/upb/sink.h",
        "third_party/upb/upb/json_encode.h",
        "third_party/upb/upb/json_decode.h",
        "third_party/upb/upb/handlers-inl.h",
        "third_party/upb/upb/handlers.c",
        "third_party/upb/upb/bindings/",
        "third_party/upb/upb/json/",
        "third_party/upb/upb/pb/",
      ],
      sources: [
        "src/core/ext/filters/",
        "src/core/ext/transport/",
        "src/core/ext/upb-generated/",
        "src/core/ext/upbdefs-generated/",
        "src/core/ext/xds/",
        "src/core/lib/",
        "src/core/plugin_registry/grpc_plugin_registry.cc",
        "src/core/tsi/",
        "third_party/re2/re2/",
        "third_party/re2/util/",
        "third_party/upb/upb/",
        "third_party/upb/third_party/wyhash/wyhash.h",
        "third_party/xxhash/xxhash.h",
      ],
      publicHeadersPath: "spm-core-include",
      cSettings: [
        .headerSearchPath("./"),
        .headerSearchPath("include/"),
        .headerSearchPath("third_party/re2/"),
        .headerSearchPath("third_party/upb/"),
        .headerSearchPath("third_party/xxhash/"),
        .headerSearchPath("src/core/ext/upb-generated/"),
        .headerSearchPath("src/core/ext/upbdefs-generated/"),
        .define("GRPC_ARES", to: "0"),
        .unsafeFlags(["-Wno-module-import-in-extern-c"]),
      ],
      linkerSettings: [
        .linkedFramework("CoreFoundation"),
        .linkedLibrary("z"),
      ]
    ),
    .target(
      name: "gRPC-cpp",
      dependencies: [
        .product(name:"abseil", package: "abseil"),
        "gRPC-Core",
      ],
      path: ".",
      exclude: [
        "src/cpp/client/cronet_credentials.cc",
        "src/cpp/client/channel_test_peer.cc",
        "src/cpp/common/alts_util.cc",
        "src/cpp/common/alts_context.cc",
        "src/cpp/common/insecure_create_auth_context.cc",
        "src/cpp/server/admin/",
        "src/cpp/server/channelz/",
        "src/cpp/server/csds/",
        "src/cpp/server/load_reporter/",
        "src/cpp/ext/",
        "src/cpp/util/core_stats.cc",
        "src/cpp/util/core_stats.h",
        "src/cpp/util/error_details.cc",
      ],
      sources: [
        "src/cpp/",
      ],
      publicHeadersPath: "spm-cpp-include",
      cSettings: [
        .headerSearchPath("./"),
        .headerSearchPath("include/"),
        .headerSearchPath("third_party/upb/"),
        .headerSearchPath("src/core/ext/upb-generated"),
        .unsafeFlags(["-Wno-module-import-in-extern-c"]),
      ]
    ),
  ],
  cLanguageStandard: .gnu11,
  cxxLanguageStandard: .cxx11
)


// automatically generated by the FlatBuffers compiler, do not modify
// swiftlint:disable all
// swiftformat:disable all
import FlatBuffers
public enum MyGame_Sample_Color: Int8, Enum {
  public typealias T = Int8
  public static var byteSize: Int { return MemoryLayout<Int8>.size }
  public var value: Int8 { return self.rawValue }
  case red = 0
  case green = 1
  case blue = 2
  public static var max: MyGame_Sample_Color { return .blue }
  public static var min: MyGame_Sample_Color { return .red }
}
public enum MyGame_Sample_Equipment: UInt8, Enum {
  public typealias T = UInt8
  public static var byteSize: Int { return MemoryLayout<UInt8>.size }
  public var value: UInt8 { return self.rawValue }
  case none_ = 0
  case weapon = 1
  public static var max: MyGame_Sample_Equipment { return .weapon }
  public static var min: MyGame_Sample_Equipment { return .none_ }
}
public struct MyGame_Sample_Vec3: NativeStruct {
  static func validateVersion() { FlatBuffersVersion_2_0_0() }
  private var _x: Float32
  private var _y: Float32
  private var _z: Float32
  public init(x: Float32, y: Float32, z: Float32) {
    _x = x
    _y = y
    _z = z
  }
  public init() {
    _x = 0.0
    _y = 0.0
    _z = 0.0
  }
  public var x: Float32 { _x }
  public var y: Float32 { _y }
  public var z: Float32 { _z }
}
public struct MyGame_Sample_Vec3_Mutable: FlatBufferObject {
  static func validateVersion() { FlatBuffersVersion_2_0_0() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Struct
  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
  public var x: Float32 { return _accessor.readBuffer(of: Float32.self, at: 0) }
}
public struct MyGame_Sample_Monster: FlatBufferObject {
  static func validateVersion() { FlatBuffersVersion_2_0_0() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Table
  public static func getRootAsMonster(bb: ByteBuffer) -> MyGame_Sample_Monster { return MyGame_Sample_Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
  private init(_ t: Table) { _accessor = t }
  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
  private enum VTOFFSET: VOffset {
    case pos = 4
    case mana = 6
    case hp = 8
    case name = 10
    case inventory = 14
    case color = 16
    case weapons = 18
    case equippedType = 20
    case equipped = 22
    case path = 24
    var v: Int32 { Int32(self.rawValue) }
    var p: VOffset { self.rawValue }
  }
  public var pos: MyGame_Sample_Vec3? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : _accessor.readBuffer(of: MyGame_Sample_Vec3.self, at: o) }
  public var mutablePos: MyGame_Sample_Vec3_Mutable? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : MyGame_Sample_Vec3_Mutable(_accessor.bb, o: o + _accessor.postion) }
  public var mana: Int16 { let o = _accessor.offset(VTOFFSET.mana.v); return o == 0 ? 150 : _accessor.readBuffer(of: Int16.self, at: o) }
  public var weaponsCount: Int32 { let o = _accessor.offset(VTOFFSET.weapons.v); return o == 0 ? 0 : _accessor.vector(count: o) }
  public func weapons(at index: Int32) -> MyGame_Sample_Weapon? { let o = _accessor.offset(VTOFFSET.weapons.v); return o == 0 ? nil : MyGame_Sample_Weapon(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
  public var equippedType: MyGame_Sample_Equipment { let o = _accessor.offset(VTOFFSET.equippedType.v); return o == 0 ? .none_ : MyGame_Sample_Equipment(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none_ }
  public func equipped<T: FlatbuffersInitializable>(type: T.Type) -> T? { let o = _accessor.offset(VTOFFSET.equipped.v); return o == 0 ? nil : _accessor.union(o) }
  public var pathCount: Int32 { let o = _accessor.offset(VTOFFSET.path.v); return o == 0 ? 0 : _accessor.vector(count: o) }
  public func path(at index: Int32) -> MyGame_Sample_Vec3? { let o = _accessor.offset(VTOFFSET.path.v); return o == 0 ? nil : _accessor.directRead(of: MyGame_Sample_Vec3.self, offset: _accessor.vector(at: o) + index * 12) }
  public func mutablePath(at index: Int32) -> MyGame_Sample_Vec3_Mutable? { let o = _accessor.offset(VTOFFSET.path.v); return o == 0 ? nil : MyGame_Sample_Vec3_Mutable(_accessor.bb, o: _accessor.vector(at: o) + index * 12) }
  public static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 11) }
  public static func add(pos: MyGame_Sample_Vec3?, _ fbb: inout FlatBufferBuilder) { guard let pos = pos else { return }; fbb.create(struct: pos, position: VTOFFSET.pos.p) }
  public static func add(mana: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: VTOFFSET.mana.p) }
  public static func add(hp: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: VTOFFSET.hp.p) }
  public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
  public static func addVectorOf(inventory: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: inventory, at: VTOFFSET.inventory.p) }
  public static func add(color: MyGame_Sample_Color, _ fbb: inout FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 2, at: VTOFFSET.color.p) }
  public static func addVectorOf(weapons: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: weapons, at: VTOFFSET.weapons.p) }
  public static func add(equippedType: MyGame_Sample_Equipment, _ fbb: inout FlatBufferBuilder) { fbb.add(element: equippedType.rawValue, def: 0, at: VTOFFSET.equippedType.p) }
  public static func add(equipped: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: equipped, at: VTOFFSET.equipped.p) }
  public static func addVectorOf(path: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: path, at: VTOFFSET.path.p) }
  public static func startVectorOfPath(_ size: Int, in builder: inout FlatBufferBuilder) {
    builder.startVector(size * MemoryLayout<MyGame_Sample_Vec3>.size, elementSize: MemoryLayout<MyGame_Sample_Vec3>.alignment)
  }
  public static func endMonster(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
  public static func createMonster(
    _ fbb: inout FlatBufferBuilder,
    pos: MyGame_Sample_Vec3? = nil,
    mana: Int16 = 150,
    hp: Int16 = 100,
    nameOffset name: Offset = Offset(),
    inventoryVectorOffset inventory: Offset = Offset(),
    color: MyGame_Sample_Color = .blue,
    weaponsVectorOffset weapons: Offset = Offset(),
    equippedType: MyGame_Sample_Equipment = .none_,
    equippedOffset equipped: Offset = Offset(),
    pathVectorOffset path: Offset = Offset()
  ) -> Offset {
    let __start = MyGame_Sample_Monster.startMonster(&fbb)
    MyGame_Sample_Monster.add(pos: pos, &fbb)
    MyGame_Sample_Monster.add(mana: mana, &fbb)
    MyGame_Sample_Monster.add(hp: hp, &fbb)
    MyGame_Sample_Monster.add(name: name, &fbb)
    MyGame_Sample_Monster.addVectorOf(inventory: inventory, &fbb)
    MyGame_Sample_Monster.add(color: color, &fbb)
    MyGame_Sample_Monster.addVectorOf(weapons: weapons, &fbb)
    MyGame_Sample_Monster.add(equippedType: equippedType, &fbb)
    MyGame_Sample_Monster.add(equipped: equipped, &fbb)
    MyGame_Sample_Monster.addVectorOf(path: path, &fbb)
    return MyGame_Sample_Monster.endMonster(&fbb, start: __start)
  }
}
public struct MyGame_Sample_Weapon: FlatBufferObject {
  static func validateVersion() { FlatBuffersVersion_2_0_0() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Table
  public static func getRootAsWeapon(bb: ByteBuffer) -> MyGame_Sample_Weapon { return MyGame_Sample_Weapon(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
  private init(_ t: Table) { _accessor = t }
  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
  private enum VTOFFSET: VOffset {
    case name = 4
    case damage = 6
    var v: Int32 { Int32(self.rawValue) }
    var p: VOffset { self.rawValue }
  }
  public var name: String? { let o = _accessor.offset(VTOFFSET.name.v); return o == 0 ? nil : _accessor.string(at: o) }
  public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.name.v) }
  public var damage: Int16 { let o = _accessor.offset(VTOFFSET.damage.v); return o == 0 ? 0 : _accessor.readBuffer(of: Int16.self, at: o) }
  public static func startWeapon(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) }
  public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
  public static func add(damage: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: damage, def: 0, at: VTOFFSET.damage.p) }
  public static func endWeapon(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
  public static func createWeapon(
    _ fbb: inout FlatBufferBuilder,
    nameOffset name: Offset = Offset(),
    damage: Int16 = 0
  ) -> Offset {
    let __start = MyGame_Sample_Weapon.startWeapon(&fbb)
    MyGame_Sample_Weapon.add(name: name, &fbb)
    MyGame_Sample_Weapon.add(damage: damage, &fbb)
    return MyGame_Sample_Weapon.endWeapon(&fbb, start: __start)
  }
}


/*
 */
import FlatBuffers
typealias Monster = MyGame_Sample_Monster
typealias Weapon = MyGame_Sample_Weapon
typealias Color = MyGame_Sample_Color
typealias Vec3 = MyGame_Sample_Vec3
func main() {
  let expectedDMG: [Int16] = [3, 5]
  let expectedNames = ["Sword", "Axe"]
  var builder = FlatBufferBuilder(initialSize: 1024)
  let weapon1Name = builder.create(string: expectedNames[0])
  let weapon2Name = builder.create(string: expectedNames[1])
  let weapon1Start = Weapon.startWeapon(&builder)
  Weapon.add(name: weapon1Name, &builder)
  Weapon.add(damage: expectedDMG[0], &builder)
  let sword = Weapon.endWeapon(&builder, start: weapon1Start)
  let weapon2Start = Weapon.startWeapon(&builder)
  Weapon.add(name: weapon2Name, &builder)
  Weapon.add(damage: expectedDMG[1], &builder)
  let axe = Weapon.endWeapon(&builder, start: weapon2Start)
  let name = builder.create(string: "Orc")
  let inventory: [Byte] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  let inventoryOffset = builder.createVector(inventory)
  let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
  let orc = Monster.createMonster(
    &builder,
    pos: MyGame_Sample_Vec3(x: 1, y: 2, z: 3),
    hp: 300,
    nameOffset: name,
    inventoryVectorOffset: inventoryOffset,
    color: .red,
    weaponsVectorOffset: weaponsOffset,
    equippedType: .weapon,
    equippedOffset: axe)
  builder.finish(offset: orc)
  let buf = builder.sizedByteArray
  let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
  assert(monster.mana == 150)
  assert(monster.hp == 300)
  assert(monster.name == "Orc")
  assert(monster.color == MyGame.Sample.Color.red)
  assert(monster.pos != nil)
  assert(monster.mutablePos != nil)
  for i in 0..<monster.inventoryCount {
    assert(i == monster.inventory(at: i))
  }
  for i in 0..<monster.weaponsCount {
    let weap = monster.weapons(at: i)
    let index = Int(i)
    assert(weap?.damage == expectedDMG[index])
    assert(weap?.name == expectedNames[index])
  }
  assert(monster.equippedType == .weapon)
  let equipped = monster.equipped(type: Weapon.self)
  assert(equipped?.name == "Axe")
  assert(equipped?.damage == 5)
  print("Monster Object is Verified")
}


// swift-tools-version:5.1
/*
 */
import PackageDescription
let package = Package(
  name: "FlatBuffers.Benchmarks.swift",
  platforms: [
    .macOS(.v10_14),
  ],
  dependencies: [
    .package(path: "../../swift"),
    .package(url: "https://github.com/google/swift-benchmark", from: "0.1.0"),
  ],
  targets: [
    .target(
      name: "FlatBuffers.Benchmarks.swift",
      dependencies: ["FlatBuffers",
                     .product(name: "Benchmark", package: "swift-benchmark")]),
  ])


main

/*
 */
import Benchmark
import CoreFoundation
import FlatBuffers
benchmark("10Strings") {
  var fb = FlatBufferBuilder(initialSize: 1<<20)
  for _ in 0..<1_000_000 {
    _ = fb.create(string: "foobarbaz")
  }
}
benchmark("100Strings") {
  var fb = FlatBufferBuilder(initialSize: 1<<20)
  for _ in 0..<1_000_000 {
    _ = fb.create(string: str)
  }
}
benchmark("FlatBufferBuilder.add") {
  var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
  for _ in 0..<1_000_000 {
    let off = fb.create(string: "T")
    let s = fb.startTable(with: 4)
    fb.add(element: 3.2, def: 0, at: 2)
    fb.add(element: 4.2, def: 0, at: 4)
    fb.add(element: 5.2, def: 0, at: 6)
    fb.add(offset: off, at: 8)
    _ = fb.endTable(at: s)
  }
}
benchmark("structs") {
  let structCount = 1_000_000
  let rawSize = ((16 * 5) * structCount) / 1024
  var fb = FlatBufferBuilder(initialSize: Int32(rawSize * 1600))
  var offsets: [Offset] = []
  for _ in 0..<structCount {
    fb.startVector(
      5 * MemoryLayout<AA>.size,
      elementSize: MemoryLayout<AA>.alignment)
    for _ in 0..<5 {
      _ = fb.create(struct: AA(a: 2.4, b: 2.4))
    }
    let vector = fb.endVector(len: 5)
    let start = fb.startTable(with: 1)
    fb.add(offset: vector, at: 4)
    offsets.append(Offset(offset: fb.endTable(at: start)))
  }
  let vector = fb.createVector(ofOffsets: offsets)
  let start = fb.startTable(with: 1)
  fb.add(offset: vector, at: 4)
  let root = Offset(offset: fb.endTable(at: start))
  fb.finish(offset: root)
}
let str = (0...99).map { _ -> String in "x" }.joined()
struct AA: NativeStruct {
  public init(a: Double, b: Double) {
    self.a = a
    self.b = b
  }
  var a: Double
  var b: Double
}
Benchmark.main()


Package

// swift-tools-version:5.1
/*
 */
import PackageDescription
let package = Package(
  name: "FlatBuffers.Test.Swift",
  platforms: [
    .iOS(.v11),
    .macOS(.v10_14),
  ],
  dependencies: [
    .package(path: "../../swift/"),
    .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.4.1"),
  ],
  targets: [
    .target(
      name: "SwiftFlatBuffers",
      dependencies: ["FlatBuffers"]),
    .testTarget(
      name: "FlatBuffers.Test.SwiftTests",
      dependencies: ["FlatBuffers", "GRPC"]),
  ])


main

/*
public func FuzzFlatbuffers(_ start: UnsafeRawPointer, _ count: Int) -> CInt {
  let bytes = UnsafeRawBufferPointer(start: start, count: count)
  do {
    var buffer = ByteBuffer(contiguousBytes: bytes, count: count)
    let _: Monster = try getCheckedRoot(byteBuffer: &buffer)
  } catch {
  }
  return 0
}


// automatically generated by the FlatBuffers compiler, do not modify
// swiftlint:disable all
// swiftformat:disable all

import FlatBuffers

public enum Color: UInt8, Enum, Verifiable {
  public typealias T = UInt8
  public static var byteSize: Int { return MemoryLayout<UInt8>.size }
  public var value: UInt8 { return self.rawValue }
  case red = 1
  ///  \brief color Green
  ///  Green is bit_flag with value (1u << 1)
  case green = 2
  ///  \brief color Blue (1u << 3)
  case blue = 8

  public static var max: Color { return .blue }
  public static var min: Color { return .red }
}

extension Color: Encodable {
  public func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    switch self {
    case .red: try container.encode("Red")
    case .green: try container.encode("Green")
    case .blue: try container.encode("Blue")
    }
  }
}

public struct Test: NativeStruct, Verifiable, FlatbuffersInitializable {

  static func validateVersion() { FlatBuffersVersion_2_0_0() }

  private var _a: Int16
  private var _b: Int8
  private let padding0__: UInt8 = 0

  public init(_ bb: ByteBuffer, o: Int32) {
    let _accessor = Struct(bb: bb, position: o)
    _a = _accessor.readBuffer(of: Int16.self, at: 0)
    _b = _accessor.readBuffer(of: Int8.self, at: 2)
  }

  public init(a: Int16, b: Int8) {
    _a = a
    _b = b
  }

  public init() {
    _a = 0
    _b = 0
  }

  public var a: Int16 { _a }
  public var b: Int8 { _b }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    try verifier.inBuffer(position: position, of: Test.self)
  }
}

extension Test: Encodable {

  enum CodingKeys: String, CodingKey {
    case a = "a"
    case b = "b"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    if a != 0 {
      try container.encodeIfPresent(a, forKey: .a)
    }
    if b != 0 {
      try container.encodeIfPresent(b, forKey: .b)
    }
  }
}

public struct Test_Mutable: FlatBufferObject {

  static func validateVersion() { FlatBuffersVersion_2_0_0() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Struct

  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }

  public var a: Int16 { return _accessor.readBuffer(of: Int16.self, at: 0) }
  public var b: Int8 { return _accessor.readBuffer(of: Int8.self, at: 2) }
}

public struct Vec3: NativeStruct, Verifiable, FlatbuffersInitializable {

  static func validateVersion() { FlatBuffersVersion_2_0_0() }

  private var _x: Float32
  private var _y: Float32
  private var _z: Float32
  private let padding0__: UInt32 = 0
  private var _test1: Double
  private var _test2: UInt8
  private let padding1__: UInt8 = 0
  private var _test3: Test
  private let padding2__: UInt16 = 0

  public init(_ bb: ByteBuffer, o: Int32) {
    let _accessor = Struct(bb: bb, position: o)
    _x = _accessor.readBuffer(of: Float32.self, at: 0)
    _y = _accessor.readBuffer(of: Float32.self, at: 4)
    _z = _accessor.readBuffer(of: Float32.self, at: 8)
    _test1 = _accessor.readBuffer(of: Double.self, at: 16)
    _test2 = _accessor.readBuffer(of: UInt8.self, at: 24)
    _test3 = Test(_accessor.bb, o: _accessor.postion + 26)
  }

  public init(x: Float32, y: Float32, z: Float32, test1: Double, test2: Color, test3: Test) {
    _x = x
    _y = y
    _z = z
    _test1 = test1
    _test2 = test2.value
    _test3 = test3
  }

  public init() {
    _x = 0.0
    _y = 0.0
    _z = 0.0
    _test1 = 0.0
    _test2 = 0
    _test3 = Test()
  }

  public var x: Float32 { _x }
  public var y: Float32 { _y }
  public var z: Float32 { _z }
  public var test1: Double { _test1 }
  public var test2: Color { Color(rawValue: _test2)! }
  public var test3: Test { _test3 }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    try verifier.inBuffer(position: position, of: Vec3.self)
  }
}

extension Vec3: Encodable {

  enum CodingKeys: String, CodingKey {
    case x = "x"
    case y = "y"
    case z = "z"
    case test1 = "test1"
    case test2 = "test2"
    case test3 = "test3"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    if x != 0.0 {
      try container.encodeIfPresent(x, forKey: .x)
    }
    if y != 0.0 {
      try container.encodeIfPresent(y, forKey: .y)
    }
    if z != 0.0 {
      try container.encodeIfPresent(z, forKey: .z)
    }
    if test1 != 0.0 {
      try container.encodeIfPresent(test1, forKey: .test1)
    }
    if test2 != .red {
      try container.encodeIfPresent(test2, forKey: .test2)
    }
    try container.encodeIfPresent(test3, forKey: .test3)
  }
}

public struct Vec3_Mutable: FlatBufferObject {

  static func validateVersion() { FlatBuffersVersion_2_0_0() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Struct

  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }

  public var x: Float32 { return _accessor.readBuffer(of: Float32.self, at: 0) }
  public var y: Float32 { return _accessor.readBuffer(of: Float32.self, at: 4) }
  public var z: Float32 { return _accessor.readBuffer(of: Float32.self, at: 8) }
  public var test1: Double { return _accessor.readBuffer(of: Double.self, at: 16) }
  public var test2: Color { return Color(rawValue: _accessor.readBuffer(of: UInt8.self, at: 24)) ?? .red }
  public var test3: Test_Mutable { return Test_Mutable(_accessor.bb, o: _accessor.postion + 26) }
}

///  an example documentation comment: "monster object"
public struct Monster: FlatBufferObject, Verifiable {

  static func validateVersion() { FlatBuffersVersion_2_0_0() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Table

  public static func getRootAsMonster(bb: ByteBuffer) -> Monster { return Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }

  private init(_ t: Table) { _accessor = t }
  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }

  private enum VTOFFSET: VOffset {
    case pos = 4
    case mana = 6
    case hp = 8
    case name = 10
    case testarrayoftables = 12
    case inventory = 14
    case color = 16
    var v: Int32 { Int32(self.rawValue) }
    var p: VOffset { self.rawValue }
  }

  public var pos: Vec3? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : _accessor.readBuffer(of: Vec3.self, at: o) }
  public var mutablePos: Vec3_Mutable? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : Vec3_Mutable(_accessor.bb, o: o + _accessor.postion) }
  public var mana: Int16 { let o = _accessor.offset(VTOFFSET.mana.v); return o == 0 ? 150 : _accessor.readBuffer(of: Int16.self, at: o) }
  public var hp: Int16 { let o = _accessor.offset(VTOFFSET.hp.v); return o == 0 ? 100 : _accessor.readBuffer(of: Int16.self, at: o) }
  public var name: String! { let o = _accessor.offset(VTOFFSET.name.v); return _accessor.string(at: o) }
  public var nameSegmentArray: [UInt8]! { return _accessor.getVector(at: VTOFFSET.name.v) }
  public var hasTestarrayoftables: Bool { let o = _accessor.offset(VTOFFSET.testarrayoftables.v); return o == 0 ? false : true }
  public var testarrayoftablesCount: Int32 { let o = _accessor.offset(VTOFFSET.testarrayoftables.v); return o == 0 ? 0 : _accessor.vector(count: o) }
  public func testarrayoftables(at index: Int32) -> Monster? { let o = _accessor.offset(VTOFFSET.testarrayoftables.v); return o == 0 ? nil : Monster(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
  public func testarrayoftablesBy(key: String) -> Monster? { let o = _accessor.offset(VTOFFSET.testarrayoftables.v); return o == 0 ? nil : Monster.lookupByKey(vector: _accessor.vector(at: o), key: key, fbb: _accessor.bb) }
  public var hasInventory: Bool { let o = _accessor.offset(VTOFFSET.inventory.v); return o == 0 ? false : true }
  public var inventoryCount: Int32 { let o = _accessor.offset(VTOFFSET.inventory.v); return o == 0 ? 0 : _accessor.vector(count: o) }
  public func inventory(at index: Int32) -> UInt8 { let o = _accessor.offset(VTOFFSET.inventory.v); return o == 0 ? 0 : _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1) }
  public var inventory: [UInt8] { return _accessor.getVector(at: VTOFFSET.inventory.v) ?? [] }
  public var color: Color { let o = _accessor.offset(VTOFFSET.color.v); return o == 0 ? .blue : Color(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .blue }
  public static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 7) }
  public static func add(pos: Vec3?, _ fbb: inout FlatBufferBuilder) { guard let pos = pos else { return }; fbb.create(struct: pos, position: VTOFFSET.pos.p) }
  public static func add(mana: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: VTOFFSET.mana.p) }
  public static func add(hp: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: VTOFFSET.hp.p) }
  public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
  public static func addVectorOf(testarrayoftables: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: testarrayoftables, at: VTOFFSET.testarrayoftables.p) }
  public static func addVectorOf(inventory: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: inventory, at: VTOFFSET.inventory.p) }
  public static func add(color: Color, _ fbb: inout FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 8, at: VTOFFSET.color.p) }
  public static func endMonster(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); fbb.require(table: end, fields: [10]); return end }
  public static func createMonster(
    _ fbb: inout FlatBufferBuilder,
    pos: Vec3? = nil,
    mana: Int16 = 150,
    hp: Int16 = 100,
    nameOffset name: Offset,
    testarrayoftablesVectorOffset testarrayoftables: Offset = Offset(),
    inventoryVectorOffset inventory: Offset = Offset(),
    color: Color = .blue
  ) -> Offset {
    let __start = Monster.startMonster(&fbb)
    Monster.add(pos: pos, &fbb)
    Monster.add(mana: mana, &fbb)
    Monster.add(hp: hp, &fbb)
    Monster.add(name: name, &fbb)
    Monster.addVectorOf(testarrayoftables: testarrayoftables, &fbb)
    Monster.addVectorOf(inventory: inventory, &fbb)
    Monster.add(color: color, &fbb)
    return Monster.endMonster(&fbb, start: __start)
  }
  public static func sortVectorOfMonster(offsets:[Offset], _ fbb: inout FlatBufferBuilder) -> Offset {
    var off = offsets
    off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: 10, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: 10, fbb: fbb.buffer), fbb: fbb.buffer) < 0 }
    return fbb.createVector(ofOffsets: off)
  }
  fileprivate static func lookupByKey(vector: Int32, key: String, fbb: ByteBuffer) -> Monster? {
    let key = key.utf8.map { $0 }
    var span = fbb.read(def: Int32.self, position: Int(vector - 4))
    var start: Int32 = 0
    while span != 0 {
      var middle = span / 2
      let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)
      let comp = Table.compare(Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: 10, fbb: fbb), key, fbb: fbb)
      if comp > 0 {
        span = middle
      } else if comp < 0 {
        middle += 1
        start += middle
        span -= middle
      } else {
        return Monster(fbb, o: tableOffset)
      }
    }
    return nil
  }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    var _v = try verifier.visitTable(at: position)
    try _v.visit(field: VTOFFSET.pos.p, fieldName: "pos", required: false, type: Vec3.self)
    try _v.visit(field: VTOFFSET.mana.p, fieldName: "mana", required: false, type: Int16.self)
    try _v.visit(field: VTOFFSET.hp.p, fieldName: "hp", required: false, type: Int16.self)
    try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: true, type: ForwardOffset<String>.self)
    try _v.visit(field: VTOFFSET.testarrayoftables.p, fieldName: "testarrayoftables", required: false, type: ForwardOffset<Vector<ForwardOffset<Monster>, Monster>>.self)
    try _v.visit(field: VTOFFSET.inventory.p, fieldName: "inventory", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
    try _v.visit(field: VTOFFSET.color.p, fieldName: "color", required: false, type: Color.self)
    _v.finish()
  }
}

extension Monster: Encodable {

  enum CodingKeys: String, CodingKey {
    case pos = "pos"
    case mana = "mana"
    case hp = "hp"
    case name = "name"
    case testarrayoftables = "testarrayoftables"
    case inventory = "inventory"
    case color = "color"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encodeIfPresent(pos, forKey: .pos)
    if mana != 150 {
      try container.encodeIfPresent(mana, forKey: .mana)
    }
    if hp != 100 {
      try container.encodeIfPresent(hp, forKey: .hp)
    }
    try container.encodeIfPresent(name, forKey: .name)
    if testarrayoftablesCount > 0 {
      var contentEncoder = container.nestedUnkeyedContainer(forKey: .testarrayoftables)
      for index in 0..<testarrayoftablesCount {
        guard let type = testarrayoftables(at: index) else { continue }
        try contentEncoder.encode(type)
      }
    }
    if inventoryCount > 0 {
      try container.encodeIfPresent(inventory, forKey: .inventory)
    }
    if color != .blue {
      try container.encodeIfPresent(color, forKey: .color)
    }
  }
}


LinuxMain

/*
 */
import XCTest
import FlatBuffers_Test_SwiftTests
var tests = [XCTestCaseEntry]()
tests += FlatBuffers_Test_SwiftTests.__allTests()
XCTMain(tests)