Remove symbolic tensor support from TensorHandle
This code is no longer being used by swift, so it seems best to
remove it to simplify the uses of TensorHandle.
PiperOrigin-RevId: 281406036
Change-Id: Ib98a84cb767fe76eee6f41d7e86c02e2eee7e98f
diff --git a/tensorflow/c/c_api_experimental.cc b/tensorflow/c/c_api_experimental.cc
index 8cbf899..8fe5a20 100644
--- a/tensorflow/c/c_api_experimental.cc
+++ b/tensorflow/c/c_api_experimental.cc
@@ -520,12 +520,6 @@
void TFE_TensorHandlePrintDebugString(TFE_TensorHandle* handle) {
auto* status = TF_NewStatus();
- if (!TFE_TensorHandleIsConcrete(handle)) {
- VLOG(1) << "Symbolic tensor: " << handle;
- TF_DeleteStatus(status);
- return;
- }
-
TF_Tensor* t = TFE_TensorHandleResolve(handle, status);
CHECK_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status);
@@ -813,204 +807,6 @@
status->status = EnableCollectiveOps(server_def, ctx);
}
-std::string tensorflow::getTF_OutputDebugString(TF_Output node) {
- return absl::Substitute("TF_Output($0, $1)", node.oper, node.index);
-}
-
-using tensorflow::getTF_OutputDebugString;
-
-TFE_TensorHandle* TFE_NewTensorHandleFromTFOutput(TF_Output t,
- TF_DataType data_type) {
- auto ret = new TFE_TensorHandle(t, data_type);
- VLOG(1) << "Storing TFOutput " << getTF_OutputDebugString(t)
- << " into tensor handle " << ret << " with internal handle "
- << ret->handle;
- return ret;
-}
-
-unsigned char TFE_TensorHandleIsConcrete(TFE_TensorHandle* handle) {
- assert(handle->handle != nullptr);
- return handle->handle->getSymbolicTensor() == nullptr;
-}
-
-TF_Output TFE_GetTFOutputFromTensorHandle(TFE_TensorHandle* handle,
- TF_Status* status) {
- if (TFE_TensorHandleIsConcrete(handle)) {
- status->status =
- tensorflow::errors::Internal("Not a symbolic tensor: ", handle);
- return TF_Output{nullptr, -1};
- }
-
- auto* sym_tensor = handle->handle->getSymbolicTensor();
- CHECK(sym_tensor != nullptr);
- auto ret = TF_Output{sym_tensor->oper, sym_tensor->index};
- VLOG(1) << "Retrieving " << getTF_OutputDebugString(ret)
- << " from tensor handle " << handle;
- CHECK_GE(sym_tensor->index, 0);
- return ret;
-}
-
-TFE_TraceContext* TFE_NewTraceContext(TF_Graph* graph) {
- return new TFE_TraceContext(graph);
-}
-
-void TFE_DeleteTraceContext(TFE_TraceContext* trace_ctx) { delete trace_ctx; }
-
-// If `handle` is already symbolic, return it. Otherwise map it to a new
-// symbolic tensor (a PlaceHolder op) and return that.
-static TF_Output getOrCreateSymbolicTensor(TFE_TraceContext* trace_ctx,
- tensorflow::TensorHandle* handle,
- TF_Status* status) {
- VLOG(1) << "Getting symbolic tensor for input tensor handle " << handle
- << ": " << handle->DebugString();
-
- auto* sym_tensor = handle->getSymbolicTensor();
- if (sym_tensor != nullptr) {
- auto ret = TF_Output{sym_tensor->oper, sym_tensor->index};
- VLOG(1) << "This handle is a symbolic tensor " << sym_tensor << ": "
- << getTF_OutputDebugString(ret);
- return ret;
- }
-
- auto find_it = trace_ctx->input_tensor_map.find(handle);
- if (find_it != trace_ctx->input_tensor_map.end()) {
- VLOG(1) << "There exists a map entry from this concrete tensor to: "
- << getTF_OutputDebugString(find_it->second);
- return find_it->second;
- }
-
- auto node_name = tensorflow::strings::StrCat("additional_input_",
- trace_ctx->node_counter++);
- VLOG(1) << "Adding a place holder node named " << node_name;
- auto* desc =
- TF_NewOperation(trace_ctx->graph, "Placeholder", node_name.c_str());
- TF_SetAttrType(desc, "dtype",
- static_cast<TF_DataType>(handle->dtype) /*TF_FLOAT*/);
- auto* result = TF_FinishOperation(desc, status);
- if (!status->status.ok()) {
- return TF_Output{nullptr, -1};
- }
-
- auto ret = TF_Output{result, 0};
- VLOG(1) << "Creating a new map entry to map to: "
- << getTF_OutputDebugString(ret);
- trace_ctx->input_tensor_map[handle] = ret;
- // `handle` could be destroyed before it's read from `input_tensor_map` (say
- // during a subsequent TFE_FinalizeInputTensorsFromTraceContext() call), so we
- // increment its ref count to extend its life span to that of `trace_ctx`.
- handle->Ref();
- VLOG(1) << "Ref count for handle " << handle
- << " is 1?: " << handle->RefCountIsOne();
- return ret;
-}
-
-TF_Operation* TFE_AddEagerOpToGraph(TFE_Op* op, TFE_TraceContext* trace_ctx,
- TFE_TensorHandle** retvals,
- int* num_retvals, TF_Status* status) {
- VLOG(1) << "Calling TFE_AddEagerOpToGraph() with op " << op << ": "
- << op->operation.DebugString();
-
- const auto& op_type = op->operation.Name();
- auto op_name =
- tensorflow::strings::StrCat(op_type, "_", trace_ctx->node_counter++);
- std::unique_ptr<TF_OperationDescription> desc(
- TF_NewOperation(trace_ctx->graph, op_type.c_str(), op_name.c_str()));
-
- VLOG(1) << "Adding attrs.";
- tensorflow::AttrValueMap attrs;
- op->operation.Attrs().FillAttrValueMap(&attrs);
- for (const auto& attr : attrs) {
- desc->node_builder.Attr(attr.first, attr.second);
- }
-
- VLOG(1) << "Adding inputs.";
- const auto& inputs = op->operation.Inputs();
- size_t inputIndex = 0;
- const tensorflow::OpDef& op_def = desc->node_builder.op_def();
- for (const tensorflow::OpDef::ArgDef& input_arg : op_def.input_arg()) {
- if (input_arg.type_list_attr().empty() && input_arg.number_attr().empty()) {
- auto symbolic_input =
- getOrCreateSymbolicTensor(trace_ctx, inputs[inputIndex++], status);
- if (!status->status.ok()) return nullptr;
- TF_AddInput(desc.get(), symbolic_input);
- continue;
- }
- size_t list_size = 0;
- if (!input_arg.type_list_attr().empty()) {
- const std::string& type_list_attr = input_arg.type_list_attr();
- const auto& attr_value = attrs[type_list_attr];
- CHECK(attr_value.value_case() == tensorflow::AttrValue::kList)
- << "Type list attribute should be a list!";
- list_size = attr_value.list().type_size();
- } else {
- CHECK(!input_arg.number_attr().empty());
- const auto& attr_value = attrs[input_arg.number_attr()];
- CHECK(attr_value.value_case() == tensorflow::AttrValue::kI)
- << "Number attribute should be int!";
- if (attr_value.i() < 0) {
- status->status = tensorflow::errors::Internal(
- "Number attribute for length should be >=0!");
- return nullptr;
- }
- list_size = attr_value.i();
- }
- std::vector<TF_Output> list_inputs(list_size);
- for (TF_Output& list_input : list_inputs) {
- list_input =
- getOrCreateSymbolicTensor(trace_ctx, inputs[inputIndex++], status);
- if (!status->status.ok()) return nullptr;
- }
- TF_AddInputList(desc.get(), list_inputs.data(), list_inputs.size());
- }
-
- auto* graph_op = TF_FinishOperation(desc.release(), status);
- if (!status->status.ok()) return nullptr;
-
- VLOG(1) << "Op finalized; setting return tensors.";
- *num_retvals = TF_OperationNumOutputs(graph_op);
- VLOG(1) << "This op has " << *num_retvals << " outputs.";
- for (int i = 0; i < *num_retvals; ++i) {
- auto output = TF_Output{graph_op, i};
- auto dtype = TF_OperationOutputType(output);
- retvals[i] = TFE_NewTensorHandleFromTFOutput(output, dtype);
- }
- return graph_op;
-}
-
-int TFE_FinalizeInputTensorsFromTraceContext(TFE_TraceContext* trace_ctx) {
- if (trace_ctx->input_tensors == nullptr) {
- trace_ctx->input_tensors =
- new std::vector<std::pair<tensorflow::TensorHandle*, TF_Output>>();
- trace_ctx->input_tensors->reserve(trace_ctx->input_tensor_map.size());
-
- for (auto input : trace_ctx->input_tensor_map) {
- trace_ctx->input_tensors->emplace_back(input.first, input.second);
- }
- }
- return trace_ctx->input_tensor_map.size();
-}
-
-TF_Output TFE_GetInputGraphNodeFromTraceContext(TFE_TraceContext* trace_ctx,
- unsigned int idx) {
- CHECK(trace_ctx->input_tensors != nullptr);
- CHECK(trace_ctx->input_tensors->size() > idx);
- return trace_ctx->input_tensors->at(idx).second;
-}
-
-TFE_TensorHandle* TFE_ConsumeInputConcreteTensorFromTraceContext(
- TFE_TraceContext* trace_ctx, unsigned int idx) {
- CHECK(trace_ctx->input_tensors != nullptr);
- CHECK(trace_ctx->input_tensors->size() > idx);
- auto* handle = trace_ctx->input_tensors->at(idx).first;
- VLOG(1) << "Ref count for internal handle " << handle
- << " is 1?: " << handle->RefCountIsOne();
- handle->Ref();
- auto* ret = new TFE_TensorHandle(handle);
- VLOG(1) << "Returning a new tensor handle " << ret << ": "
- << handle->DebugString();
- return ret;
-}
-
TF_ShapeAndTypeList* TF_NewShapeAndTypeList(int num_items) {
TF_ShapeAndTypeList* result = new TF_ShapeAndTypeList;
result->num_items = num_items;
diff --git a/tensorflow/c/c_api_experimental.h b/tensorflow/c/c_api_experimental.h
index 46ce86d..5fc260d 100644
--- a/tensorflow/c/c_api_experimental.h
+++ b/tensorflow/c/c_api_experimental.h
@@ -297,53 +297,6 @@
size_t proto_len,
TF_Status* status);
-// Create a symbolic tensor from the input graph node.
-TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_NewTensorHandleFromTFOutput(
- TF_Output t, TF_DataType data_type);
-
-// Returns 0 if the input tensor handle represents a symbolic tensor (i.e., a
-// graph node). Otherwise returns non-0.
-TF_CAPI_EXPORT extern unsigned char TFE_TensorHandleIsConcrete(
- TFE_TensorHandle* handle);
-
-// If `handle` is a symbolic tensor, return the corresponding graph node
-// represented by TF_Output. Otherwise, return an error status.
-TF_CAPI_EXPORT extern TF_Output TFE_GetTFOutputFromTensorHandle(
- TFE_TensorHandle* handle, TF_Status* status);
-
-typedef struct TFE_TraceContext TFE_TraceContext;
-
-// A trace context contains a trace graph, to which TFE_AddEagerOpToGraph()
-// calls add graph nodes as a way to symbolically execute the eager ops.
-//
-// It also contains a hash map from concrete input tensors to symbolic
-// tensors. That map will be used to create input tensors to the trace graph.
-TF_CAPI_EXPORT extern TFE_TraceContext* TFE_NewTraceContext(TF_Graph* graph);
-
-TF_CAPI_EXPORT extern void TFE_DeleteTraceContext(TFE_TraceContext* trace_ctx);
-
-// Symbolically executes `op`, by adding a corresponding node to the graph
-// associated with `trace_ctx`. This graph node outputs a set of symbolic
-// tensors in `retvals` and `num_retvals`. Returns the corresponding graph
-// operation on success, otherwise returns nullptr.
-TF_CAPI_EXPORT extern TF_Operation* TFE_AddEagerOpToGraph(
- TFE_Op* op, TFE_TraceContext* trace_ctx, TFE_TensorHandle** retvals,
- int* num_retvals, TF_Status* status);
-
-// Finalizes the trace graph and its inputs, and returns the number of inputs.
-// After this call, the next two APIs can be called to iterate over the input
-// tensors.
-TF_CAPI_EXPORT extern int TFE_FinalizeInputTensorsFromTraceContext(
- TFE_TraceContext* trace_ctx);
-
-TF_CAPI_EXPORT extern TF_Output TFE_GetInputGraphNodeFromTraceContext(
- TFE_TraceContext* trace_ctx, unsigned int idx);
-
-// Each input tensor should be consumed at most once.
-TF_CAPI_EXPORT extern TFE_TensorHandle*
-TFE_ConsumeInputConcreteTensorFromTraceContext(TFE_TraceContext* trace_ctx,
- unsigned int idx);
-
// Information about the shape of a Tensor and its type.
struct TF_ShapeAndType {
// Number of dimensions. -1 indicates unknown rank.
diff --git a/tensorflow/c/c_api_experimental_test.cc b/tensorflow/c/c_api_experimental_test.cc
index ed0ab7c..fa09f99 100644
--- a/tensorflow/c/c_api_experimental_test.cc
+++ b/tensorflow/c/c_api_experimental_test.cc
@@ -205,234 +205,6 @@
TF_DeleteStatus(status);
}
-TEST(CAPI_EXPERIMENTAL, SymbolicTensor) {
- TF_Status* status = TF_NewStatus();
- auto node = TF_Output{nullptr, 1};
- auto* sym_handle = TFE_NewTensorHandleFromTFOutput(node, TF_FLOAT);
- TFE_TensorHandlePrintDebugString(sym_handle);
- CHECK_EQ(TFE_TensorHandleDataType(sym_handle), TF_FLOAT);
- ASSERT_FALSE(TFE_TensorHandleIsConcrete(sym_handle));
- auto same_node = TFE_GetTFOutputFromTensorHandle(sym_handle, status);
- CHECK_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status);
- ASSERT_EQ(same_node.oper, node.oper);
- ASSERT_EQ(same_node.index, node.index);
- TFE_DeleteTensorHandle(sym_handle);
-
- TFE_TensorHandle* m = TestMatrixTensorHandle();
- ASSERT_TRUE(TFE_TensorHandleIsConcrete(m));
- (void)TFE_GetTFOutputFromTensorHandle(m, status);
- CHECK_EQ(TF_INTERNAL, TF_GetCode(status)) << TF_Message(status);
- TFE_DeleteTensorHandle(m);
-
- TF_DeleteStatus(status);
-}
-
-class AddEagerOpToGraphTest : public ::testing::Test {
- protected:
- AddEagerOpToGraphTest()
- : status_(TF_NewStatus()),
- eager_ctx_(nullptr),
- graph_(TF_NewGraph()),
- trace_ctx_(TFE_NewTraceContext(graph_)) {
- TFE_ContextOptions* opts = TFE_NewContextOptions();
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- eager_ctx_ = TFE_NewContext(opts, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- TFE_DeleteContextOptions(opts);
- }
-
- ~AddEagerOpToGraphTest() override {
- TFE_DeleteTraceContext(trace_ctx_);
- TF_DeleteGraph(graph_);
- TFE_DeleteContext(eager_ctx_);
- TF_DeleteStatus(status_);
- }
-
- template <typename Callable>
- void AddEagerOpToGraphAndCheck(TFE_Op* op, Callable checker) {
- TFE_TensorHandle* retvals[5];
- int num_retvals = 5;
- // Symbolically execute this op, which adds a graph node to `trace_ctx_`.
- TF_Operation* graph_op =
- TFE_AddEagerOpToGraph(op, trace_ctx_, retvals, &num_retvals, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- CHECK_NOTNULL(graph_op);
- // Check the expectations.
- checker(graph_op);
- for (int i = 0; i < num_retvals; ++i) {
- TFE_DeleteTensorHandle(retvals[i]);
- }
- }
-
- TF_Status* status_;
- TFE_Context* eager_ctx_;
- TF_Graph* graph_;
- TFE_TraceContext* trace_ctx_;
-};
-
-TEST_F(AddEagerOpToGraphTest, DebugPrintAndSymbolicExecution) {
- TFE_TensorHandle* m = TestMatrixTensorHandle();
- TFE_Op* op = MatMulOp(eager_ctx_, m, m);
-
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- TFE_OpPrintDebugString(op);
-
- TFE_TensorHandle* retvals[5];
- int num_retvals = 5;
- // Symbolically execute this op, which adds a graph node to `trace_ctx`.
- TFE_AddEagerOpToGraph(op, trace_ctx_, retvals, &num_retvals, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
-
- int num_inputs = TFE_FinalizeInputTensorsFromTraceContext(trace_ctx_);
- CHECK_EQ(num_inputs, 1);
- auto input_sym_tensor = TFE_GetInputGraphNodeFromTraceContext(trace_ctx_,
- /*idx*/ 0);
-
- LOG(INFO) << tensorflow::getTF_OutputDebugString(input_sym_tensor);
- auto handle = TFE_ConsumeInputConcreteTensorFromTraceContext(trace_ctx_,
- /*idx*/ 0);
- TFE_TensorHandlePrintDebugString(handle);
- TFE_DeleteTensorHandle(handle);
-
- CHECK_EQ(num_retvals, 1);
- CHECK_EQ(TFE_TensorHandleDataType(retvals[0]), TF_FLOAT);
-
- TFE_DeleteTensorHandle(retvals[0]);
- TFE_DeleteTensorHandle(m);
- TFE_DeleteOp(op);
-}
-
-TEST_F(AddEagerOpToGraphTest, ValueAttributesArePreserved) {
- // Create MinOp
- TFE_TensorHandle* axis = TestAxisTensorHandle();
- TFE_Op* op = MinOp(eager_ctx_, axis, axis);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
-
- // Check the attributes set by the call to MinOp above.
- AddEagerOpToGraphAndCheck(op, [this, &axis](TF_Operation* graph_op) {
- unsigned char value;
- TF_OperationGetAttrBool(graph_op, "keep_dims", &value, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- CHECK_EQ(value, 1);
- TF_DataType dtype;
- TF_OperationGetAttrType(graph_op, "Tidx", &dtype, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- CHECK_EQ(dtype, TF_INT32);
- TF_OperationGetAttrType(graph_op, "T", &dtype, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- CHECK_EQ(dtype, TFE_TensorHandleDataType(axis));
- });
- TFE_DeleteTensorHandle(axis);
- TFE_DeleteOp(op);
-}
-
-TEST_F(AddEagerOpToGraphTest, ListAttributesArePreserved) {
- // Create a "Squeeze" operator with list attributes.
- TFE_TensorHandle* axis = TestAxisTensorHandle();
- TFE_Op* squeeze = TFE_NewOp(eager_ctx_, "Squeeze", status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- TFE_OpAddInput(squeeze, axis, status_);
- TFE_OpSetAttrType(squeeze, "T", TF_INT32);
- std::vector<int64_t> boundaries = {1, 2, 3, 4};
- TFE_OpSetAttrIntList(squeeze, "squeeze_dims", boundaries.data(),
- boundaries.size());
- // Check attributes are preserved.
- AddEagerOpToGraphAndCheck(
- squeeze, [this, &boundaries](TF_Operation* squeeze_graph_op) {
- TF_DataType dtype;
- TF_OperationGetAttrType(squeeze_graph_op, "T", &dtype, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- CHECK_EQ(dtype, TF_INT32);
- std::unique_ptr<int64_t[]> list(new int64_t[boundaries.size()]);
- TF_OperationGetAttrIntList(squeeze_graph_op, "squeeze_dims", list.get(),
- boundaries.size(), status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- EXPECT_TRUE(std::equal(list.get(), list.get() + boundaries.size(),
- boundaries.begin()));
- });
- TFE_DeleteTensorHandle(axis);
- TFE_DeleteOp(squeeze);
-}
-
-TEST_F(AddEagerOpToGraphTest, ListInputsAreAddedCorrectly) {
- TFE_TensorHandle* scalar = TestScalarTensorHandle(static_cast<float>(1));
- TFE_Op* identityn = TFE_NewOp(eager_ctx_, "IdentityN", status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- constexpr size_t kNumInputs = 3;
- for (size_t i = 0; i < kNumInputs; ++i) {
- TFE_OpAddInput(identityn, scalar, status_);
- }
- TF_DataType types[kNumInputs] = {TF_FLOAT, TF_FLOAT, TF_FLOAT};
- TFE_OpSetAttrTypeList(identityn, "T", types, kNumInputs);
- AddEagerOpToGraphAndCheck(
- identityn, [this, kNumInputs](TF_Operation* graph_op) {
- EXPECT_EQ(TF_OperationNumInputs(graph_op), kNumInputs);
- EXPECT_EQ(TF_OperationInputListLength(graph_op, "input", status_),
- kNumInputs);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- EXPECT_EQ(TF_OperationOutputListLength(graph_op, "output", status_),
- kNumInputs);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- });
- TFE_DeleteTensorHandle(scalar);
- TFE_DeleteOp(identityn);
-}
-
-TEST_F(AddEagerOpToGraphTest, NumberAttributesAreHandledCorrectly) {
- TFE_TensorHandle* matrix = TestMatrixTensorHandle();
- TFE_TensorHandle* axis = TestAxisTensorHandle();
- TFE_Op* concatv2 = TFE_NewOp(eager_ctx_, "ConcatV2", status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- TFE_OpSetAttrType(concatv2, "T", TF_FLOAT);
- TFE_OpSetAttrInt(concatv2, "N", 2);
- TFE_OpSetAttrType(concatv2, "Tidx", TF_INT32);
- constexpr size_t kNumInputs = 2;
- for (size_t i = 0; i < kNumInputs; ++i) {
- TFE_OpAddInput(concatv2, matrix, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- }
- TFE_OpAddInput(concatv2, axis, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- AddEagerOpToGraphAndCheck(
- concatv2, [this, kNumInputs](TF_Operation* graph_op) {
- EXPECT_EQ(TF_OperationNumInputs(graph_op), kNumInputs + 1);
- int64_t attrN;
- TF_OperationGetAttrInt(graph_op, "N", &attrN, status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- EXPECT_EQ(attrN, kNumInputs);
- EXPECT_EQ(TF_OperationInputListLength(graph_op, "values", status_),
- kNumInputs);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- });
- TFE_DeleteTensorHandle(axis);
- TFE_DeleteTensorHandle(matrix);
- TFE_DeleteOp(concatv2);
-}
-
-TEST_F(AddEagerOpToGraphTest,
- GeneratesInternalErrorsForInvalidNumberAttributes) {
- TFE_TensorHandle* matrix = TestMatrixTensorHandle();
- TFE_TensorHandle* axis = TestAxisTensorHandle();
- int num_retvals = 5;
- TFE_TensorHandle* retvals[5];
-
- TFE_Op* concatv2 = TFE_NewOp(eager_ctx_, "ConcatV2", status_);
- CHECK_EQ(TF_OK, TF_GetCode(status_)) << TF_Message(status_);
- TFE_OpSetAttrType(concatv2, "T", TF_FLOAT);
- TFE_OpSetAttrInt(concatv2, "N", -1);
- TFE_OpSetAttrType(concatv2, "Tidx", TF_INT32);
-
- TF_Operation* graph_op = TFE_AddEagerOpToGraph(concatv2, trace_ctx_, retvals,
- &num_retvals, status_);
- EXPECT_EQ(graph_op, nullptr);
- EXPECT_EQ(status_->status.error_message(),
- "Number attribute for length should be >=0!");
-
- TFE_DeleteOp(concatv2);
- TFE_DeleteTensorHandle(axis);
- TFE_DeleteTensorHandle(matrix);
-}
-
class ShapeInferenceTest : public ::testing::Test {
protected:
ShapeInferenceTest()
diff --git a/tensorflow/c/eager/c_api_internal.h b/tensorflow/c/eager/c_api_internal.h
index 56ee1e0..024ed66 100644
--- a/tensorflow/c/eager/c_api_internal.h
+++ b/tensorflow/c/eager/c_api_internal.h
@@ -103,12 +103,6 @@
}
tensorflow::TensorHandle* handle;
-
- // Create a symbolic tensor.
- TFE_TensorHandle(TF_Output t, TF_DataType dtype)
- : handle(new tensorflow::TensorHandle(
- tensorflow::OutputGraphNode{t.oper, t.index},
- static_cast<tensorflow::DataType>(dtype))) {}
};
struct TFE_TensorDebugInfo {
@@ -285,26 +279,6 @@
const char* attr_name, TF_Status* status);
} // namespace tensorflow
-struct TFE_TraceContext {
- TF_Graph* const graph;
-
- unsigned int node_counter = 0;
- // Each tensor handle will have its ref count incremented when it's added as a
- // map key, and decremented when this object is destroyed.
- std::map<tensorflow::TensorHandle*, TF_Output> input_tensor_map;
- std::vector<std::pair<tensorflow::TensorHandle*, TF_Output>>* input_tensors =
- nullptr;
-
- explicit TFE_TraceContext(TF_Graph* graph) : graph(graph) {}
-
- ~TFE_TraceContext() {
- delete input_tensors;
- for (auto input : input_tensor_map) {
- input.first->Unref();
- }
- }
-};
-
struct TFE_CancellationManager {
tensorflow::CancellationManager cancellation_manager;
};
diff --git a/tensorflow/core/common_runtime/eager/tensor_handle.cc b/tensorflow/core/common_runtime/eager/tensor_handle.cc
index 1be22c7..8838f17 100644
--- a/tensorflow/core/common_runtime/eager/tensor_handle.cc
+++ b/tensorflow/core/common_runtime/eager/tensor_handle.cc
@@ -261,23 +261,6 @@
}
#endif
-TensorHandle::TensorHandle(OutputGraphNode symbolic_tensor, DataType dtype)
- : dtype(dtype),
- device_(nullptr),
- op_device_(nullptr),
- resource_device_(nullptr),
-#if !defined(IS_MOBILE_PLATFORM)
- remote_op_id_(kInvalidOpId),
- remote_output_num_(kInvalidOutputNum),
-#endif
- ctx_(nullptr),
- is_remote_(false),
- symbolic_tensor_(new OutputGraphNode(symbolic_tensor)) {
- DVLOG(3) << "Creating Symbolic TensorHandle: " << this;
- // Notify immediately since this handle is already ready.
- is_ready_notification_.Notify();
-}
-
bool TensorHandle::IsReady() {
return is_ready_notification_.HasBeenNotified();
}
@@ -666,11 +649,6 @@
string TensorHandle::DebugString() const {
DVLOG(1) << "Calling TensorHandle::DebugString() on " << this;
- if (symbolic_tensor_) {
- return absl::Substitute("TF_Output($0, $1)", symbolic_tensor_->oper,
- symbolic_tensor_->index);
- }
-
string out;
strings::StrAppend(&out, "Device: ", device_ ? device_->DebugString() : "[]");
// Consider supporting non-CPU tensors (when device_ is non-NULL) if needed.
diff --git a/tensorflow/core/common_runtime/eager/tensor_handle.h b/tensorflow/core/common_runtime/eager/tensor_handle.h
index d2be6a4..a8b05e3 100644
--- a/tensorflow/core/common_runtime/eager/tensor_handle.h
+++ b/tensorflow/core/common_runtime/eager/tensor_handle.h
@@ -54,17 +54,8 @@
#include "tensorflow/core/public/session_options.h"
#include "tensorflow/core/public/version.h"
-struct TF_Operation;
-
namespace tensorflow {
-// This struct is isomorphic to TF_Output, but we cannot use the latter here due
-// to layering concerns (TF_Output is defined at the C API layer).
-struct OutputGraphNode {
- TF_Operation* oper;
- int index; // The index of the output within oper.
-};
-
// Associates a Tensor and a Device, used in the eager runtime. Internal version
// of the TFE_TensorHandle struct and the python EagerTensor class
// (unrelated to python TensorHandle).
@@ -120,9 +111,6 @@
Device* device, EagerContext* ctx, TensorHandle** h);
#endif // IS_MOBILE_PLATFORM
- // Symbolic tensor constructor.
- TensorHandle(OutputGraphNode symbolic_tensor, DataType dtype);
-
~TensorHandle() override { DVLOG(3) << "Deleting TensorHandle " << this; }
Status Tensor(const tensorflow::Tensor** t);
@@ -208,8 +196,6 @@
bool IsRemote() const { return is_remote_; }
- OutputGraphNode* getSymbolicTensor() const { return symbolic_tensor_.get(); }
-
string DebugString() const;
void SetResourceHandleDtypeAndShape(
@@ -239,8 +225,7 @@
// Device in which the op producing this tensor was executed. Equals to
// device_ for constant tensors.
// Can be nullptr if the op producing this tensor was a function executed
- // with function library runtime or if this tensor represents a symbolic
- // tensor.
+ // with function library runtime.
tensorflow::Device* const op_device_;
// If the tensor dtype is DT_RESOURCE, resource_device_ holds the device
@@ -287,11 +272,6 @@
Status is_poisoned_;
const bool is_remote_;
- // When non-NULL, this tensor handle instance represents a symbolic tensor
- // (corresponding to a graph node), whose concrete value is to be produced by
- // executing that graph node.
- std::unique_ptr<OutputGraphNode> symbolic_tensor_;
-
// If this TensorHandle 1) is a local tensor, and 2) is a resource handle or
// refers to a remote resource handle, we store data types and shapes for
// the underlying resource.