         return _ThreadLocalState.useLazyTensor
             ? LazyTensorOperation(name, outputCount)
             : TFE_Op(name, outputCount)
-    }
-}
-
-// Elements in `outputs` can come from two sources:
-// a) Symbolic tensors produced by tensor ops, and added as trace graph nodes.
-// b) Concrete tensors produced by host code (e.g. Tensor(1.0)).
-fileprivate func finalizeTraceFunction(_ name: String) -> TraceContext {
-    guard let traceContext = _RuntimeConfig.traceState.context else {
-        fatalError("Not in tracing mode!.")
-    }
-    _RuntimeConfig.traceState = .notTracing
-    traceContext.finalize(traceeBasicName: name)
-    return traceContext
-}
-
-private extension TensorArrayProtocol {
-    // The returned handles are owned by the caller.
-    var cTensorHandles: [CTensorHandle] {
-        debugLog("Getting \(self._tensorHandleCount) C handles.")
-        let buffer = UnsafeMutablePointer<CTensorHandle>.allocate(
-            capacity: Int(self._tensorHandleCount))
-        debugLog("Unpacking handles into buffer.")
-        _unpackTensorHandles(into: buffer)
-        let status = TF_NewStatus()
-        debugLog("Copying buffer content to output handles.")
-        var output: [CTensorHandle] = []
-        for i in 0..<Int(_tensorHandleCount) {
-            let address = buffer.advanced(by: i)
-            let isConcrete = TFE_TensorHandleIsConcrete(address.pointee) != 0
-            debugLog("""
-                     Copying the \(i)-th C handle \(address.pointee) with \
-                     concrete=\(isConcrete).
-                     """)
-            let newHandle = TFE_TensorHandleCopySharingTensor(address.pointee, status)
-            checkOk(status)
-            internalConsistencyCheck(newHandle != nil)
-            debugLog("""
-                     Copying the \(i)-th C handle \(address.pointee) with \
-                     concrete=\(isConcrete) to C handle create \(newHandle!).
-                     """)
-            output.append(newHandle!)
-        }
-        TF_DeleteStatus(status)
-        return output
-    }
-}
-
-private extension TensorGroup {
-    // The tensors in `input` are NOT owned by this instance.
-    init<C: Collection>(_copying input: C) where C.Element == CTensorHandle {
-        assert(Self._tensorHandleCount == input.count)
-        let buffer = UnsafeMutablePointer<CTensorHandle>.allocate(capacity: input.count)
-        let status = TF_NewStatus()
-        // copy input to buffer
-        for (i, inputTensorHandle) in input.enumerated() {
-            let address = buffer.advanced(by: i)
-            // Each tensor can be symbolic (e.g. when using this API to create a symbolic input
-            // instance to tracee) or concrete (e.g. when creating the final output of the tracee).
-            let newHandle = TFE_TensorHandleCopySharingTensor(inputTensorHandle, status)
-            checkOk(status)
-            address.initialize(to: newHandle!)
-        }
-        TF_DeleteStatus(status)
-        self.init(_owning: buffer)
-    }
-
-    init<C: Collection>(_owning input: C) where C.Element == CTensorHandle {
-        assert(Self._tensorHandleCount == input.count)
-        let buffer = UnsafeMutablePointer<CTensorHandle>.allocate(capacity: input.count)
-        let status = TF_NewStatus()
-        // copy input to buffer
-        for (i, inputTensorHandle) in input.enumerated() {
-            let address = buffer.advanced(by: i)
-            address.initialize(to: inputTensorHandle)
-        }
-        TF_DeleteStatus(status)
-        self.init(_owning: buffer)
-    }
-}
-
-// TODO: Fold this protocol into TensorArrayProtocol.
-// This requires that we move concrete implementation such as Tensor._makeInstance() to
-// TensorGroup.swift.
-public protocol _TensorArrayProtocolEnhanced: TensorArrayProtocol {
-    // Create an instance based on `inputs`, which can be symbolic (e.g., when creating a symbolic
-    // input to tracee) or concrete (e.., when creating a final output of executing the tracee).
-    func _makeInstance<C: Collection>(owning inputs: C) -> Self where C.Element == CTensorHandle
-}
-
-extension _TensorArrayProtocolEnhanced {
-    var _dtypes: [TF_DataType] {
-        let count = Int(_tensorHandleCount)
-        let buffer = UnsafeMutableBufferPointer<CTensorHandle>.allocate(capacity: count)
-        defer { buffer.deallocate() }
-        _unpackTensorHandles(into: buffer.baseAddress)
-        return buffer.map { TFE_TensorHandleDataType($0) }
-    }
-}
-
-/// Trace `fn` with newly created tensor handles and return a trace context.
-private func _trace(
-    with dtypes: [TF_DataType],
-    in fn: ([CTensorHandle]) -> [CTensorHandle]
-) -> TraceContext {
-    debugLog("""
-             Tracing over a function with \(dtypes.count) inputs.
-             """)
-
-    // Verify that we are not already tracing.
-    internalConsistencyCheck(_RuntimeConfig.traceState.context == nil,
-                             "Should not be in tracing mode already!")
-
-    // Switch to tracing mode.
-    let traceCtx = TraceContext(dtypes: dtypes)
-    _RuntimeConfig.traceState = .tracing(traceCtx)
-
-    // Handle inputs.
-    let inputSymbolicTensors = traceCtx.symbolicInputs.map {
-        TFE_NewTensorHandleFromTFOutput($0, TF_OperationOutputType($0))!
-    }
-    internalConsistencyCheck(inputSymbolicTensors.count == dtypes.count)
-
-    // Run tracee to build the trace, adding ops to the trace graph function. The tracee output can
-    // contain a mixture of symbolic and concrete tensors (see the comment block within
-    // TraceContext.finalize()).
-    debugLog("Running tracee in tracing mode.")
-    traceCtx.tracedOutputs = fn(inputSymbolicTensors)
-
-    debugLog("Finalizing trace graph function.")
-    // TAP means tensor array protocol.
-    let opType = "MyTraceFn_TAP"
-    return finalizeTraceFunction(opType)
-}
-
-private func _graphInternal<
-    State: _TensorArrayProtocolEnhanced,
-    Data: TensorGroup,
-    Result: TensorGroup
->(
-    with state: State,
-    in fn: (State, Data) -> (State, Result?)
-) -> (State, Data) -> (State, Result?) {
-    let traceContext: TraceContext = withoutActuallyEscaping(fn) { escapableFn in
-        let wrappedFn = { (inputs: [CTensorHandle]) -> [CTensorHandle] in
-            let symbolicState = state._makeInstance(owning: inputs.dropLast(Data._typeList.count))
-            let symbolicData = Data(_copying: inputs.dropFirst(Int(state._tensorHandleCount)))
-            let (outputState, outputResult) = escapableFn(symbolicState, symbolicData)
-
-            debugLog("Assembling output tensor handles.")
-            let outputs =
-                outputResult != nil
-                ? (outputState.cTensorHandles + outputResult!.cTensorHandles)
-                : outputState.cTensorHandles
-            return outputs
-        }
-        let dtypes = state._dtypes + Data._typeList.map { $0._cDataType }
-        return _trace(with: dtypes, in: wrappedFn)
-    }
-    // The result is a closure that captures and executes the trace graph function in the trace
-    // context.
-    return { (oldState: State, data: Data) -> (State, Result?) in
-        debugLog("Running trace function over state \(oldState) and data \(data).")
-
-        debugLog("Getting input state tensor handles.")
-        let inputStateTensorHandles =  oldState.cTensorHandles
-        var inputTensors = inputStateTensorHandles.map {
-            TFETensorHandle(_owning: $0)
-        }
-        debugLog("Getting input data tensor handles.")
-        let inputDataTensorHandles =  data.cTensorHandles
-        inputTensors.append(contentsOf: inputDataTensorHandles.map {
-            TFETensorHandle(_owning: $0)
-        })
-
-        debugLog("Executing trace graph function.")
-        let returnValues = traceContext.execute(traceeInputs: inputTensors)
-
-        debugLog("Creating output model instance.")
-        let newState = state._makeInstance(
-            owning: returnValues.prefix(Int(state._tensorHandleCount)))
-        let resultValues = returnValues.dropFirst(Int(state._tensorHandleCount))
-        let result: Result? = resultValues.isEmpty ? nil : Result(_owning: resultValues)
-        return (newState, result)
-    }
-}
-
-// TODO: rename this to `graph` when it's ready for end users.
-public func _graph<State: _TensorArrayProtocolEnhanced, Data: TensorGroup, Result: TensorGroup>(
-    with state: State,
-    in fn: (State, Data) -> (State, Result)
-) -> (State, Data) -> (State, Result) {
-    let graphFunction = _graphInternal(with: state, in: fn)
-    return { (state: State, data: Data) in
-        let result = graphFunction(state, data)
-        internalConsistencyCheck(result.1 != nil)
-        return (result.0, result.1!)
-    }
-}
-
-// TODO: rename this to `graph` when it's ready for end users.
-public func _graph<State: _TensorArrayProtocolEnhanced, Data: TensorGroup>(
-    with state: State,
-    in fn: (State, Data) -> State
-) -> (State, Data) -> State {
-    let graphFunction: (State, Data) -> (State, Tensor<Float>?) =
-        withoutActuallyEscaping(fn) { escapableFn in
-            let wrappedFn = {
-                // The result argument needs to a type that conforms to TensorGroup.
-                // We are arbitrarily picking Tensor<Float> here.
-                (s: State, d: Data) -> (State, Tensor<Float>?) in
-                (escapableFn(s, d), nil)
-            }
-            return _graphInternal(with: state, in: wrappedFn)
-        }
-    return { (state: State, data: Data) in graphFunction(state, data).0 }
-}
-
-/// Trace the given function `fn` and return a closure that can be used to create a
-/// `TF_Function(State)` specialized for `data`.
-public func _tffunc<State: _TensorArrayProtocolEnhanced, Data: TensorGroup>(
-    with state: State,
-    in fn: (State, Data) -> State
-) -> (Data) -> (String) {
-    let traceContext: TraceContext = withoutActuallyEscaping(fn) { escapableFn in
-        let wrappedFn = { (inputs: [CTensorHandle]) -> [CTensorHandle] in
-            let symbolicState = state._makeInstance(owning: inputs.dropLast(Data._typeList.count))
-            let symbolicData = Data(_copying: inputs.dropFirst(Int(state._tensorHandleCount)))
-            let outputState = escapableFn(symbolicState, symbolicData)
-            return outputState.cTensorHandles
-        }
-        let dtypes = state._dtypes + Data._typeList.map { $0._cDataType }
-        return _trace(with: dtypes, in: wrappedFn)
-    }
-    return {
-        data in traceContext.specializeTFFunction(with: data.cTensorHandles)
     }
 }
 

            debugLog("[Run with TF_CPP_MIN_LOG_LEVEL=0 to have TFEOps printed out]")
        }
    }
    if let traceContext = _RuntimeConfig.traceState.context {
        // convert this eager op into a trace graph node
        debugLog("Adding eager op \(op) to trace graph.")
        traceContext.addEagerOpToGraph(op, retvals, retvalCount, status)
        checkOk(status)
    } else {
        debugLog("Executing eager op \(op).")
        TFE_Execute(op, retvals, retvalCount, status)
    }
}

//===----------------------------------------------------------------------===//

#endif
import CTensorFlow

/// The configuration for the compiler runtime.
// TODO(hongm): Revisit the longer-term design.
// @_frozen // SR-9739
public enum _RuntimeConfig {
    // TODO: change this and subsequent properties from static to thread local.
    /// When false, tensorflow runtime will be initialized before running any tensor program in this
    /// process.
    static public var tensorFlowRuntimeInitialized = false
