aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/c/c_api_test.cc
diff options
context:
space:
mode:
authorGravatar Asim Shankar <ashankar@google.com>2017-07-25 10:49:37 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-07-25 11:01:49 -0700
commit4c9e344bf1b6582620b26c0a62a886d3c80e3c19 (patch)
treed59d2475f0da58363fdeb28f8b960f10ba4d29cb /tensorflow/c/c_api_test.cc
parent1ee8217f090a06deca7a451c8044530e7398398b (diff)
C API: Fix a bug with TF_OperationGetAttrTensor when TF_STRING tensors are
involved. The TensorBuffer owned by a TF_Tensor object has a different memory layout than the TensorBuffer owned by the corresponding tensorflow::Tensor object. This change consolidates conversions between the runtime's tensorflow::Tensor and the C API's TF_Tensor objects into a pair helper functions. The added test: CApiAttributesTest.StringTensor fails without corresponding changes to c_api.cc PiperOrigin-RevId: 163091789
Diffstat (limited to 'tensorflow/c/c_api_test.cc')
-rw-r--r--tensorflow/c/c_api_test.cc50
1 files changed, 40 insertions, 10 deletions
diff --git a/tensorflow/c/c_api_test.cc b/tensorflow/c/c_api_test.cc
index d6debe3b99..25b6cbd8e7 100644
--- a/tensorflow/c/c_api_test.cc
+++ b/tensorflow/c/c_api_test.cc
@@ -45,9 +45,8 @@ limitations under the License.
#include "tensorflow/core/util/equal_graph_def.h"
namespace tensorflow {
-
-bool TF_Tensor_DecodeStrings(TF_Tensor* src, Tensor* dst, TF_Status* status);
-TF_Tensor* TF_Tensor_EncodeStrings(const Tensor& src);
+TF_Tensor* TF_TensorFromTensor(const Tensor& src);
+Status TF_TensorToTensor(const TF_Tensor* src, Tensor* dst);
namespace {
@@ -146,19 +145,16 @@ void TestEncodeDecode(int line, const std::vector<string>& data) {
for (tensorflow::int64 i = 0; i < src.NumElements(); ++i) {
src.flat<string>()(i) = data[i];
}
- TF_Tensor* dst = TF_Tensor_EncodeStrings(src);
+ TF_Tensor* dst = TF_TensorFromTensor(src);
// Convert back to a C++ Tensor and ensure we get expected output.
- TF_Status* status = TF_NewStatus();
Tensor output;
- ASSERT_TRUE(TF_Tensor_DecodeStrings(dst, &output, status)) << line;
- ASSERT_EQ(TF_OK, TF_GetCode(status)) << line;
+ ASSERT_EQ(Status::OK(), TF_TensorToTensor(dst, &output)) << line;
ASSERT_EQ(src.NumElements(), output.NumElements()) << line;
for (tensorflow::int64 i = 0; i < src.NumElements(); ++i) {
ASSERT_EQ(data[i], output.flat<string>()(i)) << line;
}
- TF_DeleteStatus(status);
TF_DeleteTensor(dst);
}
}
@@ -918,7 +914,7 @@ TEST(CAPI, SavedModel) {
TF_Operation* input_op =
TF_GraphOperationByName(graph, input_op_name.c_str());
ASSERT_TRUE(input_op != nullptr);
- csession.SetInputs({{input_op, TF_Tensor_EncodeStrings(input)}});
+ csession.SetInputs({{input_op, TF_TensorFromTensor(input)}});
const tensorflow::string output_op_name =
tensorflow::ParseTensorName(output_name).first.ToString();
@@ -1636,6 +1632,39 @@ TEST_F(CApiAttributesTest, Tensor) {
TF_DeleteTensor(value);
}
+TEST_F(CApiAttributesTest, StringTensor) {
+ // Create the string-Tensor "atttribute" value.
+ char encoded[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, // array[uint64] offsets
+ 1, // varint encoded string length
+ 'A',
+ };
+ auto deallocator = [](void* data, size_t len, void* arg) {};
+ unique_tensor_ptr t_in(TF_NewTensor(TF_STRING, nullptr, 0, &encoded[0],
+ sizeof(encoded), deallocator, nullptr),
+ TF_DeleteTensor);
+
+ // Create a TF_Operation with the attribute t_in
+ auto desc = init("tensor");
+ TF_SetAttrTensor(desc, "v", t_in.get(), s_);
+ ASSERT_EQ(TF_OK, TF_GetCode(s_)) << TF_Message(s_);
+
+ auto oper = TF_FinishOperation(desc, s_);
+ ASSERT_EQ(TF_OK, TF_GetCode(s_)) << TF_Message(s_);
+
+ // Fetch the attribute back.
+ EXPECT_TF_META("v", -1, TF_ATTR_TENSOR, -1);
+ TF_Tensor* t_out = nullptr;
+ TF_OperationGetAttrTensor(oper, "v", &t_out, s_);
+ ASSERT_EQ(TF_OK, TF_GetCode(s_)) << TF_Message(s_);
+ EXPECT_EQ(TF_STRING, TF_TensorType(t_out));
+ EXPECT_EQ(0, TF_NumDims(t_out));
+ ASSERT_EQ(TF_TensorByteSize(t_in.get()), TF_TensorByteSize(t_out));
+ EXPECT_EQ(0, memcmp(TF_TensorData(t_in.get()), TF_TensorData(t_out),
+ TF_TensorByteSize(t_out)));
+ TF_DeleteTensor(t_out);
+}
+
TEST_F(CApiAttributesTest, TensorList) {
const char tensor1[] = {5, 7};
const int64_t dims1[] = {1, 2};
@@ -1647,7 +1676,8 @@ TEST_F(CApiAttributesTest, TensorList) {
auto desc = init("list(tensor)");
TF_Tensor* tmp[] = {
- Int8Tensor(dims1, ndims1, tensor1), Int8Tensor(dims2, ndims2, tensor2),
+ Int8Tensor(dims1, ndims1, tensor1),
+ Int8Tensor(dims2, ndims2, tensor2),
};
TF_SetAttrTensorList(desc, "v", tmp, TF_ARRAYSIZE(tmp), s_);
for (int i = 0; i < TF_ARRAYSIZE(tmp); ++i) {