From f040810ceb0caee9d8028c79865181e402238f89 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 26 Jun 2020 20:12:39 +0000 Subject: [PATCH 01/27] added allocated_temp function and tests --- tensorflow/c/kernels.cc | 30 +++---- tensorflow/c/kernels.h | 2 +- tensorflow/c/kernels_test.cc | 166 +++++++++++++++++++++++++++-------- 3 files changed, 145 insertions(+), 53 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index e1ece820ab7..864fd916b8b 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -264,26 +264,24 @@ TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int index, return result; } - +/* num_dims must equal the array size of dims */ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, - int64_t* dims, int num_dims, TF_Status* Status, TF_Tensor* tf_tensor_temp){ + int64_t* dims, int num_dims, TF_Status* status){ auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); - // convert inputs to compatible types for API call - // tensorflow::DataType enum_of_dtype = tensorflow::EnumToDataType::v(); - // temp_tensor = Tensor(dtype, shape); - // tensorflow::TensorShape s(dimensions); + TF_SetStatus(status, TF_OK, ""); tensorflow::TensorShape shape; for(int i = 0; i < num_dims; ++i){ shape.AddDim(dims[i]); } - tensorflow::Status allocation_status; - tensorflow::Tensor tensor_temp; - TF_TensorToTensor(tf_tensor_temp, &tensor_temp); - allocation_status = cc_ctx->allocate_temp(static_cast(dtype), shape, &tensor_temp); - tf_tensor_temp = TF_TensorFromTensor(tensor_temp, &allocation_status); - - - - - // Status allocation_status = cc_ctx->allocate_temp() + tensorflow::Status s; + tensorflow::Tensor tensor_temp; + TF_Tensor* tf_tensor_temp; + s = cc_ctx->allocate_temp(static_cast(dtype), shape, &tensor_temp); + if (s.ok()){ + tf_tensor_temp = TF_TensorFromTensor(tensor_temp, &s); + } + if (s.ok()){ + ::tensorflow::Set_TF_Status_from_Status(status, s); + return tf_tensor_temp; + } } diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index 9fcfdbeddc2..9ae4f4b182d 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -191,7 +191,7 @@ TF_CAPI_EXPORT TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, size_t len, TF_Status* status); TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, - int64_t* dims, int num_dims, TF_Status* Status); + int64_t* dims, int num_dims, TF_Status* status); #ifdef __cplusplus diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 423302741de..738c1e12c80 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -360,6 +360,17 @@ class DeviceKernelOpTest : public OpsTestBase { #endif }; +// Helper function for tests that validates that the tensor has +// shape and type corresponding to dims and dtype. +void validate_tensor(TF_Tensor* tensor, int64_t* dims, int64_t num_dims, + TF_DataType dtype); + +// Helper function for tests that copies data of length +// tensor_size_bytes from values to tensor +template +void set_tensor_data(TF_Tensor* tensor, T* values, size_t tensor_size_bytes, + TF_OpKernelContext* ctx); + REGISTER_OP("AllocateOutputOp1").Output("output1: float"); TEST_F(DeviceKernelOpTest, TestAllocateOutputSizeOne) { @@ -371,22 +382,11 @@ TEST_F(DeviceKernelOpTest, TestAllocateOutputSizeOne) { TF_Tensor* output = TF_AllocateOutput( /*context=*/ctx, /*index=*/0, /*dtype=*/TF_FLOAT, /*dims=*/&dim, /*num_dims=*/1, /*len=*/tensor_size_bytes, s); - EXPECT_EQ(TF_OK, TF_GetCode(s)); - EXPECT_EQ(TF_FLOAT, TF_TensorType(output)); - EXPECT_EQ(1, TF_NumDims(output)); - EXPECT_EQ(1, TF_Dim(output, 0)); - + validate_tensor(output, &dim, 1, TF_FLOAT); + // Set output to 3 - float* data = reinterpret_cast(TF_TensorData(output)); - float value = 3.0f; -#if GOOGLE_CUDA - OpKernelContext* cc_ctx = reinterpret_cast(ctx); - cc_ctx->eigen_gpu_device().memcpyHostToDevice(data, &value, - tensor_size_bytes); -#else - *data = value; -#endif - + float values[1] = {3.0f}; + set_tensor_data(output, values, tensor_size_bytes, ctx); TF_DeleteStatus(s); TF_DeleteTensor(output); }; @@ -409,12 +409,8 @@ TEST_F(DeviceKernelOpTest, TestAllocateEmptyOutput) { TF_Tensor* output = TF_AllocateOutput( /*context=*/ctx, /*index=*/0, /*dtype=*/TF_FLOAT, /*dims=*/&dim, /*num_dims=*/1, /*len=*/0, s); - EXPECT_EQ(TF_OK, TF_GetCode(s)); - EXPECT_EQ(TF_FLOAT, TF_TensorType(output)); - EXPECT_EQ(1, TF_NumDims(output)); - EXPECT_EQ(0, TF_Dim(output, 0)); - + validate_tensor(output, &dim, 1, TF_FLOAT); TF_DeleteStatus(s); TF_DeleteTensor(output); }; @@ -434,27 +430,16 @@ TEST_F(DeviceKernelOpTest, TestAllocateOutputSize2x3) { TF_Status* s = TF_NewStatus(); // Allocate 2x3 output int64_t dim[2] = {2, 3}; - size_t tensor_size_bytes = 6 * TF_DataTypeSize(TF_FLOAT); + size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT) * 6; TF_Tensor* output = TF_AllocateOutput( /*context=*/ctx, /*index=*/0, /*dtype=*/TF_FLOAT, /*dims=*/dim, /*num_dims=*/2, /*len=*/tensor_size_bytes, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); - EXPECT_EQ(TF_FLOAT, TF_TensorType(output)); - EXPECT_EQ(2, TF_NumDims(output)); - EXPECT_EQ(2, TF_Dim(output, 0)); - EXPECT_EQ(3, TF_Dim(output, 1)); + validate_tensor(output, dim, 2, TF_FLOAT); // Set output to [1 2 3 4 5 6] - void* data = TF_TensorData(output); - float value[6] = {1, 2, 3, 4, 5, 6}; -#if GOOGLE_CUDA - OpKernelContext* cc_ctx = reinterpret_cast(ctx); - cc_ctx->eigen_gpu_device().memcpyHostToDevice(data, value, - tensor_size_bytes); -#else - memcpy(data, value, tensor_size_bytes); -#endif - + float values[6] = {1, 2, 3, 4, 5, 6}; + set_tensor_data(output, values, tensor_size_bytes, ctx); TF_DeleteStatus(s); TF_DeleteTensor(output); }; @@ -466,4 +451,113 @@ TEST_F(DeviceKernelOpTest, TestAllocateOutputSize2x3) { EXPECT_EQ("Tensor", output->DebugString(100)); } -} // namespace tensorflow + +REGISTER_OP("AllocateTempOp1").Output("output1: float"); + +TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { + auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { + // Allocate output + TF_Status* s = TF_NewStatus(); + int64_t dim = 1; + TF_Tensor* output = TF_AllocateTemp( + /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, + /*num_dims=*/1, s); + size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT); + EXPECT_EQ(TF_OK, TF_GetCode(s)); + validate_tensor(output, &dim, 1, TF_FLOAT); + + // Set output to 3 + float values[1] = {3.0f}; + set_tensor_data(output, values, tensor_size_bytes, ctx); + TF_SetOutput(ctx, 0, output, s); + TF_DeleteStatus(s); + TF_DeleteTensor(output); + }; + + SetupOp("AllocateTempOp1", "AllocateTemp1", my_compute_func); + + TF_ASSERT_OK(RunOpKernel()); + Tensor* output = GetOutput(0); + EXPECT_EQ("Tensor", + output->DebugString(100)); +} + +REGISTER_OP("AllocateTempOp0").Output("output1: float"); + +TEST_F(DeviceKernelOpTest, TestAllocateTempEmpty) { + auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { + TF_Status* s = TF_NewStatus(); + // Allocate empty output + int64_t dim = 0; + TF_Tensor* output = TF_AllocateTemp( + /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, + /*num_dims=*/1, s); + EXPECT_EQ(TF_OK, TF_GetCode(s)); + validate_tensor(output, &dim, 1, TF_FLOAT); + TF_SetOutput(ctx, 0, output, s); + TF_DeleteStatus(s); + TF_DeleteTensor(output); + }; + + SetupOp("AllocateTempOp0", "AllocateTemp0", my_compute_func); + + TF_ASSERT_OK(RunOpKernel()); + Tensor* output = GetOutput(0); + EXPECT_EQ("Tensor", + output->DebugString(100)); +} + +REGISTER_OP("AllocateTempOp2x3").Output("output1: float"); + +TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { + auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { + TF_Status* s = TF_NewStatus(); + size_t tensor_size_bytes = 6 * TF_DataTypeSize(TF_FLOAT); + // Allocate 2x3 output + int64_t dim[2] = {2, 3}; + TF_Tensor* output = TF_AllocateTemp( + /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/dim, + /*num_dims=*/2, s); + EXPECT_EQ(TF_OK, TF_GetCode(s)); + validate_tensor(output, dim, 2, TF_FLOAT); + + // Set output to [1 2 3 4 5 6] + void* data = TF_TensorData(output); + float values[6] = {1, 2, 3, 4, 5, 6}; + set_tensor_data(output, values, tensor_size_bytes, ctx); + TF_SetOutput(ctx, 0, output, s); + TF_DeleteStatus(s); + TF_DeleteTensor(output); + }; + + SetupOp("AllocateTempOp2x3", "AllocateTempOp2x3", my_compute_func); + + TF_ASSERT_OK(RunOpKernel()); + Tensor* output = GetOutput(0); + EXPECT_EQ("Tensor", + output->DebugString(100)); +} + +void validate_tensor(TF_Tensor* tensor, int64_t* dims, int64_t num_dims, + TF_DataType dtype){ + EXPECT_EQ(TF_FLOAT, TF_TensorType(tensor)); + EXPECT_EQ(num_dims, TF_NumDims(tensor)); + for(int i = 0; i < num_dims; ++i){ + EXPECT_EQ(dims[i], TF_Dim(tensor, i)); + } +} + +template +void set_tensor_data(TF_Tensor* tensor, T* values, size_t tensor_size_bytes, + TF_OpKernelContext* ctx){ + T* data = reinterpret_cast(TF_TensorData(tensor)); +#if GOOGLE_CUDA + OpKernelContext* cc_ctx = reinterpret_cast(ctx); + cc_ctx->eigen_gpu_device().memcpyHostToDevice(data, values, + tensor_size_bytes); +#else + memcpy(data, values, tensor_size_bytes); +#endif +} + +} // namespace tensorflow \ No newline at end of file From 7fd7e0a3776a3bb5e5ee7d5bec99e498f19834a8 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 26 Jun 2020 22:00:05 +0000 Subject: [PATCH 02/27] added comments to allocate_temp --- tensorflow/c/kernels.cc | 1 - tensorflow/c/kernels.h | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 864fd916b8b..80b5234b52d 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -264,7 +264,6 @@ TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int index, return result; } -/* num_dims must equal the array size of dims */ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, int64_t* dims, int num_dims, TF_Status* status){ auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index 9ae4f4b182d..e450511da3a 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -190,6 +190,11 @@ TF_CAPI_EXPORT TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int64_t* dims, int num_dims, size_t len, TF_Status* status); +// Allocates a temporary Tensor of the specified type and shape. The +// Tensor must not be used after kernel construction is +// complete. + +// num_dims must equal the size of array dims TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, int64_t* dims, int num_dims, TF_Status* status); From b2c450ae75cfc07aee0adadf116f150c35cae3b5 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 26 Jun 2020 22:32:02 +0000 Subject: [PATCH 03/27] completed priority --- tensorflow/c/kernels.cc | 5 +++++ tensorflow/c/kernels.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 80b5234b52d..905219c6e16 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -100,6 +100,11 @@ void TF_KernelBuilder_HostMemory(TF_KernelBuilder* kernel_builder, kernel_builder->cc_builder->HostMemory(arg_name); } +void TF_KernelBuilder_Priority(TF_KernelBuilder* kernel_builder, + int32_t priority_number){ + kernel_builder->cc_builder->Priority(priority_number); +} + namespace tensorflow { namespace { diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index e450511da3a..b245dd8a7fc 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -107,6 +107,10 @@ TF_CAPI_EXPORT extern void TF_KernelBuilder_TypeConstraint( TF_CAPI_EXPORT extern void TF_KernelBuilder_HostMemory( TF_KernelBuilder* kernel_builder, const char* arg_name); +// Specify a priority number for this kernel. +TF_CAPI_EXPORT extern void TF_KernelBuilder_Priority( + TF_KernelBuilder* kernel_builder, int32_t priority_number); + // Register the given kernel builder with the TensorFlow runtime. If // registration fails, the given status will be populated. // From 1a5a6c3f8199d7a18f1e1a2b86c5638f38928fe4 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Wed, 1 Jul 2020 00:00:05 +0000 Subject: [PATCH 04/27] fixed indentation errors --- tensorflow/c/kernels.cc | 5 +++-- tensorflow/c/kernels.h | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 905219c6e16..525e19513e1 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -270,7 +270,7 @@ TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int index, } TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, - int64_t* dims, int num_dims, TF_Status* status){ + int64_t* dims, int num_dims, TF_Status* status){ auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); TF_SetStatus(status, TF_OK, ""); tensorflow::TensorShape shape; @@ -280,7 +280,8 @@ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, tensorflow::Status s; tensorflow::Tensor tensor_temp; TF_Tensor* tf_tensor_temp; - s = cc_ctx->allocate_temp(static_cast(dtype), shape, &tensor_temp); + s = cc_ctx->allocate_temp(static_cast(dtype), shape, + &tensor_temp); if (s.ok()){ tf_tensor_temp = TF_TensorFromTensor(tensor_temp, &s); } diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index b245dd8a7fc..5c8f36cde9c 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -199,8 +199,11 @@ TF_CAPI_EXPORT TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, // complete. // num_dims must equal the size of array dims -TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, - int64_t* dims, int num_dims, TF_Status* status); +TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, + TF_DataType dtype, + int64_t* dims, + int num_dims, + TF_Status* status); #ifdef __cplusplus From cec1c9c22e6bae059d7888d0e2902e11b53df3be Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Mon, 13 Jul 2020 19:40:17 +0000 Subject: [PATCH 05/27] added TF_AllocatorAttributes --- tensorflow/c/tf_tensor.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index acdf053e63a..ce08a8d2678 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -45,6 +45,16 @@ limitations under the License. extern "C" { #endif +// Allocator Attributes used for tensor allocation +struct TF_AllocatorAttributes { + size_t struct_size; + unsigned char on_host; +} TF_AllocatorAttributes; + + +#define TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE \ + TF_OFFSET_OF_END(TF_AllocatorAttributes, on_host) + // -------------------------------------------------------------------------- // TF_Tensor holds a multi-dimensional array of elements of a single data type. // For all types other than TF_STRING, the data buffer stores elements From 9e1e8b58541e1d34e70339de37a167c8c7662e45 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Mon, 13 Jul 2020 19:43:23 +0000 Subject: [PATCH 06/27] updated file path to upstream/master for mergeability --- tensorflow/c/kernels.cc | 30 ------- tensorflow/c/kernels.h | 15 ---- tensorflow/c/kernels_test.cc | 166 ++++++++--------------------------- 3 files changed, 36 insertions(+), 175 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index a8da95c6eac..3021a38e888 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -25,7 +25,6 @@ limitations under the License. #include "tensorflow/core/framework/register_types.h" #include "tensorflow/core/framework/types.h" #include "tensorflow/core/platform/types.h" -#include "tensorflow/core/framework/tensor_shape.h" // This file forms the basis of a stable ABI for third-party kernel // implementations. It is crucial that changes to this file are made cautiously @@ -98,11 +97,6 @@ void TF_KernelBuilder_HostMemory(TF_KernelBuilder* kernel_builder, kernel_builder->cc_builder->HostMemory(arg_name); } -void TF_KernelBuilder_Priority(TF_KernelBuilder* kernel_builder, - int32_t priority_number){ - kernel_builder->cc_builder->Priority(priority_number); -} - namespace tensorflow { namespace { @@ -273,27 +267,3 @@ TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int index, } return tf_tensor; } - -TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, - int64_t* dims, int num_dims, TF_Status* status){ - auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); - TF_SetStatus(status, TF_OK, ""); - tensorflow::TensorShape shape; - for(int i = 0; i < num_dims; ++i){ - shape.AddDim(dims[i]); - } - tensorflow::Status s; - tensorflow::Tensor tensor; - TF_Tensor* tf_tensor; - s = cc_ctx->allocate_temp(static_cast(dtype), shape, &tensor); - if (!s.ok()){ - ::tensorflow::Set_TF_Status_from_Status(status, s); - return nullptr; - } - tf_tensor = TF_TensorFromTensor(tensor, &s); - if (!s.ok()){ - ::tensorflow::Set_TF_Status_from_Status(status, s); - return nullptr; - } - return tf_tensor; -} diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index 1891ce31a23..084717c1d9e 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -107,10 +107,6 @@ TF_CAPI_EXPORT extern void TF_KernelBuilder_TypeConstraint( TF_CAPI_EXPORT extern void TF_KernelBuilder_HostMemory( TF_KernelBuilder* kernel_builder, const char* arg_name); -// Specify a priority number for this kernel. -TF_CAPI_EXPORT extern void TF_KernelBuilder_Priority( - TF_KernelBuilder* kernel_builder, int32_t priority_number); - // Register the given kernel builder with the TensorFlow runtime. If // registration fails, the given status will be populated. // @@ -194,17 +190,6 @@ TF_CAPI_EXPORT TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int64_t* dims, int num_dims, size_t len, TF_Status* status); -// Allocates a temporary Tensor of the specified type and shape. Devices -// such as GPUs that enqueue Ops for lazy execution may retain references -// to the temporary tensors after the Op's Compute method has run. - -// num_dims must equal the size of array dims -TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, - TF_DataType dtype, - int64_t* dims, int num_dims, - TF_Status* status); - - #ifdef __cplusplus } /* end extern "C" */ #endif diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 738c1e12c80..423302741de 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -360,17 +360,6 @@ class DeviceKernelOpTest : public OpsTestBase { #endif }; -// Helper function for tests that validates that the tensor has -// shape and type corresponding to dims and dtype. -void validate_tensor(TF_Tensor* tensor, int64_t* dims, int64_t num_dims, - TF_DataType dtype); - -// Helper function for tests that copies data of length -// tensor_size_bytes from values to tensor -template -void set_tensor_data(TF_Tensor* tensor, T* values, size_t tensor_size_bytes, - TF_OpKernelContext* ctx); - REGISTER_OP("AllocateOutputOp1").Output("output1: float"); TEST_F(DeviceKernelOpTest, TestAllocateOutputSizeOne) { @@ -382,11 +371,22 @@ TEST_F(DeviceKernelOpTest, TestAllocateOutputSizeOne) { TF_Tensor* output = TF_AllocateOutput( /*context=*/ctx, /*index=*/0, /*dtype=*/TF_FLOAT, /*dims=*/&dim, /*num_dims=*/1, /*len=*/tensor_size_bytes, s); - validate_tensor(output, &dim, 1, TF_FLOAT); - + EXPECT_EQ(TF_OK, TF_GetCode(s)); + EXPECT_EQ(TF_FLOAT, TF_TensorType(output)); + EXPECT_EQ(1, TF_NumDims(output)); + EXPECT_EQ(1, TF_Dim(output, 0)); + // Set output to 3 - float values[1] = {3.0f}; - set_tensor_data(output, values, tensor_size_bytes, ctx); + float* data = reinterpret_cast(TF_TensorData(output)); + float value = 3.0f; +#if GOOGLE_CUDA + OpKernelContext* cc_ctx = reinterpret_cast(ctx); + cc_ctx->eigen_gpu_device().memcpyHostToDevice(data, &value, + tensor_size_bytes); +#else + *data = value; +#endif + TF_DeleteStatus(s); TF_DeleteTensor(output); }; @@ -409,8 +409,12 @@ TEST_F(DeviceKernelOpTest, TestAllocateEmptyOutput) { TF_Tensor* output = TF_AllocateOutput( /*context=*/ctx, /*index=*/0, /*dtype=*/TF_FLOAT, /*dims=*/&dim, /*num_dims=*/1, /*len=*/0, s); + EXPECT_EQ(TF_OK, TF_GetCode(s)); - validate_tensor(output, &dim, 1, TF_FLOAT); + EXPECT_EQ(TF_FLOAT, TF_TensorType(output)); + EXPECT_EQ(1, TF_NumDims(output)); + EXPECT_EQ(0, TF_Dim(output, 0)); + TF_DeleteStatus(s); TF_DeleteTensor(output); }; @@ -430,16 +434,27 @@ TEST_F(DeviceKernelOpTest, TestAllocateOutputSize2x3) { TF_Status* s = TF_NewStatus(); // Allocate 2x3 output int64_t dim[2] = {2, 3}; - size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT) * 6; + size_t tensor_size_bytes = 6 * TF_DataTypeSize(TF_FLOAT); TF_Tensor* output = TF_AllocateOutput( /*context=*/ctx, /*index=*/0, /*dtype=*/TF_FLOAT, /*dims=*/dim, /*num_dims=*/2, /*len=*/tensor_size_bytes, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); - validate_tensor(output, dim, 2, TF_FLOAT); + EXPECT_EQ(TF_FLOAT, TF_TensorType(output)); + EXPECT_EQ(2, TF_NumDims(output)); + EXPECT_EQ(2, TF_Dim(output, 0)); + EXPECT_EQ(3, TF_Dim(output, 1)); // Set output to [1 2 3 4 5 6] - float values[6] = {1, 2, 3, 4, 5, 6}; - set_tensor_data(output, values, tensor_size_bytes, ctx); + void* data = TF_TensorData(output); + float value[6] = {1, 2, 3, 4, 5, 6}; +#if GOOGLE_CUDA + OpKernelContext* cc_ctx = reinterpret_cast(ctx); + cc_ctx->eigen_gpu_device().memcpyHostToDevice(data, value, + tensor_size_bytes); +#else + memcpy(data, value, tensor_size_bytes); +#endif + TF_DeleteStatus(s); TF_DeleteTensor(output); }; @@ -451,113 +466,4 @@ TEST_F(DeviceKernelOpTest, TestAllocateOutputSize2x3) { EXPECT_EQ("Tensor", output->DebugString(100)); } - -REGISTER_OP("AllocateTempOp1").Output("output1: float"); - -TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { - auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { - // Allocate output - TF_Status* s = TF_NewStatus(); - int64_t dim = 1; - TF_Tensor* output = TF_AllocateTemp( - /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, s); - size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT); - EXPECT_EQ(TF_OK, TF_GetCode(s)); - validate_tensor(output, &dim, 1, TF_FLOAT); - - // Set output to 3 - float values[1] = {3.0f}; - set_tensor_data(output, values, tensor_size_bytes, ctx); - TF_SetOutput(ctx, 0, output, s); - TF_DeleteStatus(s); - TF_DeleteTensor(output); - }; - - SetupOp("AllocateTempOp1", "AllocateTemp1", my_compute_func); - - TF_ASSERT_OK(RunOpKernel()); - Tensor* output = GetOutput(0); - EXPECT_EQ("Tensor", - output->DebugString(100)); -} - -REGISTER_OP("AllocateTempOp0").Output("output1: float"); - -TEST_F(DeviceKernelOpTest, TestAllocateTempEmpty) { - auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { - TF_Status* s = TF_NewStatus(); - // Allocate empty output - int64_t dim = 0; - TF_Tensor* output = TF_AllocateTemp( - /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, s); - EXPECT_EQ(TF_OK, TF_GetCode(s)); - validate_tensor(output, &dim, 1, TF_FLOAT); - TF_SetOutput(ctx, 0, output, s); - TF_DeleteStatus(s); - TF_DeleteTensor(output); - }; - - SetupOp("AllocateTempOp0", "AllocateTemp0", my_compute_func); - - TF_ASSERT_OK(RunOpKernel()); - Tensor* output = GetOutput(0); - EXPECT_EQ("Tensor", - output->DebugString(100)); -} - -REGISTER_OP("AllocateTempOp2x3").Output("output1: float"); - -TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { - auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { - TF_Status* s = TF_NewStatus(); - size_t tensor_size_bytes = 6 * TF_DataTypeSize(TF_FLOAT); - // Allocate 2x3 output - int64_t dim[2] = {2, 3}; - TF_Tensor* output = TF_AllocateTemp( - /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/dim, - /*num_dims=*/2, s); - EXPECT_EQ(TF_OK, TF_GetCode(s)); - validate_tensor(output, dim, 2, TF_FLOAT); - - // Set output to [1 2 3 4 5 6] - void* data = TF_TensorData(output); - float values[6] = {1, 2, 3, 4, 5, 6}; - set_tensor_data(output, values, tensor_size_bytes, ctx); - TF_SetOutput(ctx, 0, output, s); - TF_DeleteStatus(s); - TF_DeleteTensor(output); - }; - - SetupOp("AllocateTempOp2x3", "AllocateTempOp2x3", my_compute_func); - - TF_ASSERT_OK(RunOpKernel()); - Tensor* output = GetOutput(0); - EXPECT_EQ("Tensor", - output->DebugString(100)); -} - -void validate_tensor(TF_Tensor* tensor, int64_t* dims, int64_t num_dims, - TF_DataType dtype){ - EXPECT_EQ(TF_FLOAT, TF_TensorType(tensor)); - EXPECT_EQ(num_dims, TF_NumDims(tensor)); - for(int i = 0; i < num_dims; ++i){ - EXPECT_EQ(dims[i], TF_Dim(tensor, i)); - } -} - -template -void set_tensor_data(TF_Tensor* tensor, T* values, size_t tensor_size_bytes, - TF_OpKernelContext* ctx){ - T* data = reinterpret_cast(TF_TensorData(tensor)); -#if GOOGLE_CUDA - OpKernelContext* cc_ctx = reinterpret_cast(ctx); - cc_ctx->eigen_gpu_device().memcpyHostToDevice(data, values, - tensor_size_bytes); -#else - memcpy(data, values, tensor_size_bytes); -#endif -} - -} // namespace tensorflow \ No newline at end of file +} // namespace tensorflow From b8ec531156f669a343d45309e12ed900b1f9ebc8 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Mon, 13 Jul 2020 21:24:42 +0000 Subject: [PATCH 07/27] added TF_OFFSET_OF_END and typedef to struct --- tensorflow/c/tf_tensor.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index ce08a8d2678..dc659db1f7c 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -45,8 +45,15 @@ limitations under the License. extern "C" { #endif -// Allocator Attributes used for tensor allocation -struct TF_AllocatorAttributes { +// Macro used to calculate struct size for maintaining ABI stability across +// different struct implementations. +#ifndef TF_OFFSET_OF_END +#define TF_OFFSET_OF_END(TYPE, MEMBER) (offsetof(TYPE, MEMBER) + \ + sizeof(((TYPE *)0)->MEMBER)) +#endif // TF_OFFSET_OF_END + +// Allocator Attributes used for tensor allocation. +typedef struct TF_AllocatorAttributes { size_t struct_size; unsigned char on_host; } TF_AllocatorAttributes; From ef90c47a66ba3bdb438b096c740cc8c83949b049 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Tue, 14 Jul 2020 16:56:04 +0000 Subject: [PATCH 08/27] added comment to on_host flag --- tensorflow/c/tf_tensor.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index dc659db1f7c..fa1bc80138c 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -55,6 +55,7 @@ extern "C" { // Allocator Attributes used for tensor allocation. typedef struct TF_AllocatorAttributes { size_t struct_size; + // Set flag to 0 for CPU allocation, else 1. unsigned char on_host; } TF_AllocatorAttributes; From 165baf2eb9ca13a3d0613369ad0d00c7fe466abd Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Tue, 14 Jul 2020 17:11:04 +0000 Subject: [PATCH 09/27] fixed comment for on_host bool --- tensorflow/c/tf_tensor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index fa1bc80138c..190e545dcd9 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -1,4 +1,4 @@ -/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ extern "C" { // Allocator Attributes used for tensor allocation. typedef struct TF_AllocatorAttributes { size_t struct_size; - // Set flag to 0 for CPU allocation, else 1. + // Set boolean to 0 for CPU allocation, else 1. unsigned char on_host; } TF_AllocatorAttributes; From 4c4223eac9a0dae3ee9e901bdaa554a2cdd54279 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Tue, 14 Jul 2020 18:50:53 +0000 Subject: [PATCH 10/27] fixed Copyright date --- tensorflow/c/tf_tensor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index 190e545dcd9..237b41cbb10 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -1,4 +1,4 @@ -/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 1007559c220863de8c0051154229a1f556852813 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 24 Jul 2020 15:50:08 +0000 Subject: [PATCH 11/27] added allocator attributes to allocate_temp --- tensorflow/c/kernels.cc | 10 ++++++++-- tensorflow/c/kernels.h | 7 +++---- tensorflow/c/kernels_test.cc | 15 ++++++++++++--- tensorflow/c/tf_tensor.h | 2 +- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 3ac0af13b2d..4d9b35861f9 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -277,18 +277,24 @@ TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int index, } TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, - int64_t* dims, int num_dims, TF_Status* status){ + int64_t* dims, int num_dims, + TF_AllocatorAttributes attributes, + TF_Status* status) { auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); TF_SetStatus(status, TF_OK, ""); tensorflow::TensorShape shape; for(int i = 0; i < num_dims; ++i){ shape.AddDim(dims[i]); } + tensorflow::AllocatorAttributes allocator_attr; + if (attributes.on_host) { + allocator_attr.set_on_host(true); + } tensorflow::Status s; tensorflow::Tensor tensor_temp; TF_Tensor* tf_tensor_temp; s = cc_ctx->allocate_temp(static_cast(dtype), shape, - &tensor_temp); + &tensor_temp, allocator_attr); if (s.ok()){ tf_tensor_temp = TF_TensorFromTensor(tensor_temp, &s); } diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index 5c8f36cde9c..658ad3ac404 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -20,6 +20,7 @@ limitations under the License. #include "tensorflow/c/tf_datatype.h" #include "tensorflow/c/tf_status.h" +#include "tensorflow/c/tf_tensor.h" // Macro to control visibility of exported symbols in the shared library (.so, // .dylib, .dll). @@ -200,10 +201,8 @@ TF_CAPI_EXPORT TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, // num_dims must equal the size of array dims TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, - TF_DataType dtype, - int64_t* dims, - int num_dims, - TF_Status* status); + TF_DataType dtype, int64_t* dims, int num_dims, TF_AllocatorAttributes + alloc_attrs, TF_Status* status); #ifdef __cplusplus diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 738c1e12c80..780cd8958d4 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -459,9 +459,12 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { // Allocate output TF_Status* s = TF_NewStatus(); int64_t dim = 1; + TF_AllocatorAttributes alloc_attrs; + alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; + alloc_attrs.on_host = 1; TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, s); + /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); @@ -489,9 +492,12 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempEmpty) { TF_Status* s = TF_NewStatus(); // Allocate empty output int64_t dim = 0; + TF_AllocatorAttributes alloc_attrs; + alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; + alloc_attrs.on_host = 1; TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, s); + /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); TF_SetOutput(ctx, 0, output, s); @@ -515,9 +521,12 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { size_t tensor_size_bytes = 6 * TF_DataTypeSize(TF_FLOAT); // Allocate 2x3 output int64_t dim[2] = {2, 3}; + TF_AllocatorAttributes alloc_attrs; + alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; + alloc_attrs.on_host = 1; TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/dim, - /*num_dims=*/2, s); + /*num_dims=*/2, /*allocator_attributes*/ alloc_attrs, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, dim, 2, TF_FLOAT); diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index d7ea6c0a8ce..d8d8155e8cd 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -58,7 +58,7 @@ extern "C" { // Allocator Attributes used for tensor allocation. typedef struct TF_AllocatorAttributes { size_t struct_size; - // Set boolean to 0 for CPU allocation, else 1. + // Set boolean to 1 for CPU allocation, else 0. unsigned char on_host; } TF_AllocatorAttributes; From 2de04ca046406bd208f4f04ceaf938b520e1281f Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 24 Jul 2020 20:48:09 +0000 Subject: [PATCH 12/27] clean up --- tensorflow/c/kernels.cc | 6 +++--- tensorflow/c/kernels_test.cc | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 4d9b35861f9..8c2c4e67b3a 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -283,7 +283,7 @@ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); TF_SetStatus(status, TF_OK, ""); tensorflow::TensorShape shape; - for(int i = 0; i < num_dims; ++i){ + for (int i = 0; i < num_dims; ++i) { shape.AddDim(dims[i]); } tensorflow::AllocatorAttributes allocator_attr; @@ -295,10 +295,10 @@ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, TF_Tensor* tf_tensor_temp; s = cc_ctx->allocate_temp(static_cast(dtype), shape, &tensor_temp, allocator_attr); - if (s.ok()){ + if (s.ok()) { tf_tensor_temp = TF_TensorFromTensor(tensor_temp, &s); } - if (s.ok()){ + if (s.ok()) { ::tensorflow::Set_TF_Status_from_Status(status, s); return tf_tensor_temp; } diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 780cd8958d4..4c925402cb7 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -456,7 +456,7 @@ REGISTER_OP("AllocateTempOp1").Output("output1: float"); TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { - // Allocate output + // Allocate scalar TF_Tensor TF_Status* s = TF_NewStatus(); int64_t dim = 1; TF_AllocatorAttributes alloc_attrs; @@ -469,7 +469,7 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); - // Set output to 3 + // Set TF_Tensor value to 3 float values[1] = {3.0f}; set_tensor_data(output, values, tensor_size_bytes, ctx); TF_SetOutput(ctx, 0, output, s); @@ -490,7 +490,7 @@ REGISTER_OP("AllocateTempOp0").Output("output1: float"); TEST_F(DeviceKernelOpTest, TestAllocateTempEmpty) { auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { TF_Status* s = TF_NewStatus(); - // Allocate empty output + // Allocate empty TF_Tensor int64_t dim = 0; TF_AllocatorAttributes alloc_attrs; alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; @@ -519,7 +519,7 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { TF_Status* s = TF_NewStatus(); size_t tensor_size_bytes = 6 * TF_DataTypeSize(TF_FLOAT); - // Allocate 2x3 output + // Allocate 2x3 TF_Tensor int64_t dim[2] = {2, 3}; TF_AllocatorAttributes alloc_attrs; alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; @@ -530,7 +530,7 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, dim, 2, TF_FLOAT); - // Set output to [1 2 3 4 5 6] + // Set TF_Tensor values to [1 2 3 4 5 6] void* data = TF_TensorData(output); float values[6] = {1, 2, 3, 4, 5, 6}; set_tensor_data(output, values, tensor_size_bytes, ctx); @@ -558,7 +558,7 @@ void validate_tensor(TF_Tensor* tensor, int64_t* dims, int64_t num_dims, template void set_tensor_data(TF_Tensor* tensor, T* values, size_t tensor_size_bytes, - TF_OpKernelContext* ctx){ + TF_OpKernelContext* ctx) { T* data = reinterpret_cast(TF_TensorData(tensor)); #if GOOGLE_CUDA OpKernelContext* cc_ctx = reinterpret_cast(ctx); From aa3291d4402ce91dfd40ed32801fd70b1b6d5447 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 24 Jul 2020 20:56:17 +0000 Subject: [PATCH 13/27] clean up --- tensorflow/c/kernels.cc | 11 +- tensorflow/c/kernels.h | 2 +- ...-summary_op-needs-tstring-C-API-sync.patch | 377 ------------------ tensorflow/c/kernels/BUILD | 39 -- tensorflow/c/kernels/diff.patch | 0 tensorflow/c/kernels/ops/summary.cc | 70 ---- 6 files changed, 5 insertions(+), 494 deletions(-) delete mode 100644 tensorflow/c/kernels/0001-summary_op-needs-tstring-C-API-sync.patch delete mode 100644 tensorflow/c/kernels/diff.patch delete mode 100644 tensorflow/c/kernels/ops/summary.cc diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 8c2c4e67b3a..5bd3989e66c 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -26,9 +26,6 @@ limitations under the License. #include "tensorflow/core/framework/types.h" #include "tensorflow/core/platform/types.h" -#include "tensorflow/core/framework/tensor_shape.h" -#include "tensorflow/core/lib/gtl/array_slice.h" - // This file forms the basis of a stable ABI for third-party kernel // implementations. It is crucial that changes to this file are made cautiously // and with a focus on maintaining both source and binary compatibility. @@ -100,9 +97,9 @@ void TF_KernelBuilder_HostMemory(TF_KernelBuilder* kernel_builder, kernel_builder->cc_builder->HostMemory(arg_name); } -void TF_KernelBuilder_Priority(TF_KernelBuilder* kernel_builder, - int32_t priority_number){ - kernel_builder->cc_builder->Priority(priority_number); +void TF_KernelBuilder_Priority(TF_KernelBuilder* kernel_builder, + int32_t priority_number) { + kernel_builder->cc_builder->Priority(priority_number); } namespace tensorflow { @@ -277,7 +274,7 @@ TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int index, } TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, - int64_t* dims, int num_dims, + int64_t* dims, int num_dims, TF_AllocatorAttributes attributes, TF_Status* status) { auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index 658ad3ac404..a564bd42797 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -110,7 +110,7 @@ TF_CAPI_EXPORT extern void TF_KernelBuilder_HostMemory( // Specify a priority number for this kernel. TF_CAPI_EXPORT extern void TF_KernelBuilder_Priority( - TF_KernelBuilder* kernel_builder, int32_t priority_number); + TF_KernelBuilder* kernel_builder, int32_t priority_number); // Register the given kernel builder with the TensorFlow runtime. If // registration fails, the given status will be populated. diff --git a/tensorflow/c/kernels/0001-summary_op-needs-tstring-C-API-sync.patch b/tensorflow/c/kernels/0001-summary_op-needs-tstring-C-API-sync.patch deleted file mode 100644 index 856f4a554c3..00000000000 --- a/tensorflow/c/kernels/0001-summary_op-needs-tstring-C-API-sync.patch +++ /dev/null @@ -1,377 +0,0 @@ -From 9134fbb13794865a45288d2e722ad47c362e0ae4 Mon Sep 17 00:00:00 2001 -From: Daniel Nguyen -Date: Thu, 18 Jun 2020 23:13:11 +0000 -Subject: [PATCH] summary_op needs tstring C API sync - ---- - tensorflow/c/kernels/diff.patch | 0 - tensorflow/c/kernels/ops/summary.cc | 70 ++++++++++ - tensorflow/c/kernels/summary_op.cc | 171 ++++++++++++++++++++++++ - tensorflow/c/kernels/summary_op_test.cc | 96 +++++++++++++ - 4 files changed, 337 insertions(+) - create mode 100644 tensorflow/c/kernels/diff.patch - create mode 100644 tensorflow/c/kernels/ops/summary.cc - create mode 100644 tensorflow/c/kernels/summary_op.cc - create mode 100644 tensorflow/c/kernels/summary_op_test.cc - -diff --git a/tensorflow/c/kernels/diff.patch b/tensorflow/c/kernels/diff.patch -new file mode 100644 -index 0000000000..e69de29bb2 -diff --git a/tensorflow/c/kernels/ops/summary.cc b/tensorflow/c/kernels/ops/summary.cc -new file mode 100644 -index 0000000000..550a663d00 ---- /dev/null -+++ b/tensorflow/c/kernels/ops/summary.cc -@@ -0,0 +1,70 @@ -+/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. -+ -+Licensed under the Apache License, Version 2.0 (the "License"); -+you may not use this file except in compliance with the License. -+You may obtain a copy of the License at -+ -+ http://www.apache.org/licenses/LICENSE-2.0 -+ -+Unless required by applicable law or agreed to in writing, software -+distributed under the License is distributed on an "AS IS" BASIS, -+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+See the License for the specific language governing permissions and -+limitations under the License. -+==============================================================================*/ -+ -+#include -+#include -+ -+#include "tensorflow/c/ops.h" -+#include "tensorflow/core/framework/selective_registration.h" -+#include "tensorflow/core/platform/logging.h" -+#include "tensorflow/core/platform/macros.h" -+ -+ -+static void TF_ScalarSummary_shape_inference_fn(TF_ShapeInferenceContext* ctx, -+ TF_Status* status) { -+ TF_ShapeHandle* result = TF_NewShapeHandle(); -+ // TODO: what to do in the case of unknown input shape? -+ if (TF_GetCode(status) == TF_OK && -+ !TF_ShapeInferenceContextRankKnown(ctx, result)) { -+ TF_ShapeInferenceContextSetUnknownShape(ctx, status); -+ CHECK_EQ(TF_OK, TF_GetCode(status)) -+ << "Error while setting unknown shape function"; -+ TF_DeleteShapeHandle(result); -+ return; -+ } -+ // make shape handle a scalar value (empty shape) -+ if (TF_GetCode(status) == TF_OK) { -+ TF_ShapeInferenceContextSetOutput(ctx, 0, result, status); -+ CHECK_EQ(TF_OK, TF_GetCode(status)) -+ << "Error while setting shape function"; -+ } -+ TF_DeleteShapeHandle(result); -+} -+ -+void Register_ScalarSummaryOp() { -+ TF_Status* status = TF_NewStatus(); -+ -+ TF_OpDefinitionBuilder* op_builder = TF_NewOpDefinitionBuilder("SummaryScalar"); -+ TF_OpDefinitionBuilderAddInput(op_builder, "tags: string"); -+ TF_OpDefinitionBuilderAddInput(op_builder, "values: T"); -+ TF_OpDefinitionBuilderAddOutput(op_builder, "summary: string"); -+ TF_OpDefinitionBuilderAddAttr( -+ op_builder, -+ "T: realnumbertype"); -+ TF_OpDefinitionBuilderSetShapeInferenceFunction(op_builder, -+ &TF_ScalarSummary_shape_inference_fn); -+ -+ TF_RegisterOpDefinition(op_builder, status); -+ CHECK_EQ(TF_GetCode(status), TF_OK) -+ << "TF_ScalarSummary op registration failed: " << TF_Message(status); -+ TF_DeleteStatus(status); -+} -+ -+TF_ATTRIBUTE_UNUSED static bool SummaryScalarOpRegistered = []() { -+ if (SHOULD_REGISTER_OP("SummaryScalar")) { -+ Register_ScalarSummaryOp(); -+ } -+ return true; -+}(); -diff --git a/tensorflow/c/kernels/summary_op.cc b/tensorflow/c/kernels/summary_op.cc -new file mode 100644 -index 0000000000..3a78d321d7 ---- /dev/null -+++ b/tensorflow/c/kernels/summary_op.cc -@@ -0,0 +1,171 @@ -+ -+/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. -+ -+Licensed under the Apache License, Version 2.0 (the "License"); -+you may not use this file except in compliance with the License. -+You may obtain a copy of the License at -+ -+ http://www.apache.org/licenses/LICENSE-2.0 -+ -+Unless required by applicable law or agreed to in writing, software -+distributed under the License is distributed on an "AS IS" BASIS, -+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+See the License for the specific language governing permissions and -+limitations under the License. -+==============================================================================*/ -+ -+#include -+ -+#include "tensorflow/c/kernels.h" -+#include "tensorflow/c/ops.h" -+#include "tensorflow/c/tf_tensor.h" -+#include "tensorflow/core/framework/common_shape_fns.h" -+#include "tensorflow/core/framework/op.h" -+#include "tensorflow/core/framework/selective_registration.h" -+#include "tensorflow/core/framework/shape_inference.h" -+#include "tensorflow/core/platform/macros.h" -+#include "tensorflow/core/framework/summary.pb.h" -+#include "tensorflow/core/platform/protobuf.h" -+#include "tensorflow/core/framework/register_types.h" -+ -+#include "tensorflow/core/framework/types.h" -+ -+// BitcastOp implements a bitcast kernel, creating an output tensor that shares -+// the same data buffer as the input but with a different shape and/or data -+// type. Its inputs are: -+// -+// * the input tensor -+// * an attribute named "T" containing the TF_DataType of the input tensor -+// * an attribute named "type" containing the TF_DataType of the output tensor -+// -+// Given an input tensor of shape [...], if the input DataType "T" is larger -+// than the output DataType "type", then the shape changes from [...] -+// to [..., sizeof(T)/sizeof(type)]. -+// -+// If "T" is smaller than "type", the operator requires that the rightmost -+// dimension be equal to sizeof(type)/sizeof(T). The shape then goes from -+// [..., sizeof(type)/sizeof(T)] to [...]. -+// -+// Bitcast is implemented as a low-level cast, so machines with different endian -+// orderings will give different results. -+ -+static void* SummaryScalarOp_Create(TF_OpKernelConstruction* ctx) { -+ // TODO: replace with a void* pointer type later -+ int a = 4; -+ return static_cast(&a); -+} -+ -+static void SummaryScalarOp_Delete(void* kernel) { -+ return; -+} -+ -+bool IsSameSize(TF_Tensor* tensor1, TF_Tensor* tensor2){ -+ if (TF_NumDims(tensor1) != TF_NumDims(tensor2)){ -+ return false; -+ } -+ for(int d = 0; d < TF_NumDims(tensor1); d++){ -+ if (TF_Dim(tensor1, d) != TF_Dim(tensor2, d)){ -+ return false; -+ } -+ } -+ return true; -+} -+ -+template -+static void SummaryScalarOp_Compute(void* kernel, TF_OpKernelContext* ctx) { -+ TF_Tensor* tags; -+ TF_Tensor* values; -+ TF_Status* status = TF_NewStatus(); -+ TF_GetInput(ctx, 0, &tags, status); -+ CHECK_EQ(TF_OK, TF_GetCode(status)) -+ << "Error while getting input"; -+ if (TF_GetCode(status) == TF_OK){ -+ TF_GetInput(ctx, 1, &values, status); -+ } -+ CHECK_EQ(TF_OK, TF_GetCode(status)) -+ << "Error while getting input"; -+ if (TF_GetCode(status) == TF_OK) { -+ if (!IsSameSize(tags, values)) { -+ std::ostringstream err; -+ err << "tags and values not the same shape: "; -+ TF_SetStatus(status, TF_INVALID_ARGUMENT, err.str().c_str()); -+ } -+ } -+ -+ tensorflow::Summary s; -+ if (TF_GetCode(status) == TF_OK) { -+ auto Ttags_array = static_cast(TF_TensorData(tags)); -+ auto values_array = static_cast(TF_TensorData(values)); -+ for (int i = 0; i < TF_TensorElementCount(tags); ++i){ -+ tensorflow::Summary::Value* v = s.add_value(); -+ TF_TString_Init(Ttags_array[i]); -+ v->set_tag(TF_TString_GetDataPointer(Ttags_array[i]), TF_TString_GetSize(Ttags_array[i])); -+ v->set_simple_value(float(values_array[i])); -+ } -+ -+ -+ // TF_Tensor* summary_tensor = TF_AllocateOutput(ctx, 0, TF_ExpectedOutputDataType(ctx, 0), 0, 0) -+ -+ // TF_Tensor* output = TF_AllocateTensor(k->output_data_type, dims, 0, -+ // TF_DataTypeSize(k->output_data_type)); -+ // if (TF_GetCode(status) == TF_OK) { -+ // TF_SetOutput(ctx, 0, output, status); -+ // } -+ // TF_DeleteTensor(output); -+ } -+ -+ // if (TF_GetCode(status) != TF_OK) { -+ // TF_OpKernelContext_Failure(ctx, status); -+ // } -+ // TF_DeleteStatus(status); -+ // TF_DeleteTensor(tags); -+} -+ -+template -+void RegisterSummaryScalarOpKernel() { -+ TF_Status* status = TF_NewStatus(); -+ { -+ auto* builder = TF_NewKernelBuilder("SummaryScalar", tensorflow::DEVICE_CPU, -+ &SummaryScalarOp_Create, &SummaryScalarOp_Compute, -+ &SummaryScalarOp_Delete); -+ TF_KernelBuilder_TypeConstraint(builder, "T", static_cast(tensorflow::DataTypeToEnum::v()), status); -+ CHECK_EQ(TF_OK, TF_GetCode(status)) -+ << "Error while adding type constraint"; -+ TF_RegisterKernelBuilder("SummaryScalar", builder, status); -+ CHECK_EQ(TF_OK, TF_GetCode(status)) -+ << "Error while registering Summary Scalar kernel"; -+ } -+// template -+// #if GOOGLE_CUDA -+// { -+// auto* builder = TF_NewKernelBuilder("SummaryScalar", tensorflow::DEVICE_GPU, -+// &SummaryScalarOp_Create, &SummaryScalarOp_Compute, -+// &SummaryScalarOp_Delete); -+// TF_RegisterKernelBuilder("SummaryScalar", builder, status); -+// CHECK_EQ(TF_OK, TF_GetCode(status)) -+// << "Error while registering CUDA SummaryScalar kernel"; -+// } -+// #endif -+ -+ TF_DeleteStatus(status); -+} -+ -+// A dummy static variable initialized by a lambda whose side-effect is to -+// register the bitcast kernel. -+ -+ -+TF_ATTRIBUTE_UNUSED static bool IsSummaryScalarOpKernelRegistered = []() { -+ if (SHOULD_REGISTER_OP_KERNEL("SummaryScalar")) { -+ RegisterSummaryScalarOpKernel(); -+ RegisterSummaryScalarOpKernel(); -+ RegisterSummaryScalarOpKernel(); -+ RegisterSummaryScalarOpKernel(); -+ RegisterSummaryScalarOpKernel(); -+ RegisterSummaryScalarOpKernel(); -+ RegisterSummaryScalarOpKernel(); -+ RegisterSummaryScalarOpKernel(); -+ RegisterSummaryScalarOpKernel(); -+ } -+ return true; -+}(); -+ -diff --git a/tensorflow/c/kernels/summary_op_test.cc b/tensorflow/c/kernels/summary_op_test.cc -new file mode 100644 -index 0000000000..fd6199abd6 ---- /dev/null -+++ b/tensorflow/c/kernels/summary_op_test.cc -@@ -0,0 +1,96 @@ -+/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. -+ -+Licensed under the Apache License, Version 2.0 (the "License"); -+you may not use this file except in compliance with the License. -+You may obtain a copy of the License at -+ -+ http://www.apache.org/licenses/LICENSE-2.0 -+ -+Unless required by applicable law or agreed to in writing, software -+distributed under the License is distributed on an "AS IS" BASIS, -+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+See the License for the specific language governing permissions and -+limitations under the License. -+==============================================================================*/ -+ -+#include "tensorflow/core/framework/attr_value.pb.h" -+#include "tensorflow/core/framework/attr_value_util.h" -+#include "tensorflow/core/framework/fake_input.h" -+#include "tensorflow/core/framework/node_def.pb.h" -+#include "tensorflow/core/framework/node_def_builder.h" -+#include "tensorflow/core/framework/op_kernel.h" -+#include "tensorflow/core/framework/shape_inference.h" -+#include "tensorflow/core/platform/test.h" -+ -+#include -+#include -+#include -+namespace tensorflow { -+namespace { -+ -+class DummyDevice : public DeviceBase { -+ public: -+ explicit DummyDevice(Env* env) : DeviceBase(env) {} -+ Allocator* GetAllocator(AllocatorAttributes /*attr*/) override { -+ return cpu_allocator(); -+ } -+}; -+ -+void TestScalarSummaryOp(Tensor* tags, Tensor* values, error::Code expected_code) { -+ Status status; -+ NodeDef def; -+ def.set_op("SummaryScalar"); -+ -+ def.set_device(DEVICE_CPU); -+ -+ AttrValue valuesTypeAttr; -+ SetAttrValue(values->dtype(), &valuesTypeAttr); -+ (*def.mutable_attr())["T"] = valuesTypeAttr; -+ -+ def.add_input( -+ strings::StrCat("input1: ", DataTypeString(tags->dtype()))); -+ def.add_input( -+ strings::StrCat("input2: ", DataTypeString(values->dtype()))); -+ -+ std::unique_ptr kernel = -+ CreateOpKernel(DeviceType(DEVICE_CPU), nullptr, nullptr, def, 1, &status); -+ ASSERT_TRUE(status.ok()) << status.ToString(); -+ OpKernelContext::Params params; -+ DummyDevice dummy_device(nullptr); -+ params.device = &dummy_device; -+ params.op_kernel = kernel.get(); -+ gtl::InlinedVector inputs; -+ inputs.emplace_back(tags); -+ inputs.emplace_back(values); -+ params.inputs = &inputs; -+ OpKernelContext ctx(¶ms, 1); -+ kernel->Compute(&ctx); -+ -+ ASSERT_EQ(expected_code, ctx.status().code()); -+ if (expected_code == error::OK) { -+ ASSERT_EQ(true, false) -+ << ctx.mutable_output(0)->shape().DebugString(); -+ } -+} -+ -+TEST(ScalarSummaryOpTest, Test) { -+ int vectorSize = 2; -+ Tensor tags(DT_STRING, {vectorSize}); -+ Tensor values(DT_FLOAT, {vectorSize}); -+ for (int i = 0; i < vectorSize; ++i){ -+ values.vec()(i) = static_cast(i); -+ } -+ tags.vec()(0) = "tag 1"; -+ tags.vec()(1) = "tag 2"; -+ TestScalarSummaryOp(&tags, &values, error::INVALID_ARGUMENT); -+} -+ -+ -+PartialTensorShape S(std::initializer_list dims) { -+ return PartialTensorShape(dims); -+} -+ -+ -+ -+} // namespace -+} // namespace tensorflow --- -2.27.0.111.gc72c7da667-goog - diff --git a/tensorflow/c/kernels/BUILD b/tensorflow/c/kernels/BUILD index 3ce53309841..770352c62c1 100644 --- a/tensorflow/c/kernels/BUILD +++ b/tensorflow/c/kernels/BUILD @@ -24,21 +24,6 @@ tf_kernel_library( ], ) -tf_kernel_library( - name = "summary_op", - prefix = "summary_op", - deps = [ - "//tensorflow/c:kernels", - "//tensorflow/c:ops", - "//tensorflow/c:tf_datatype", - "//tensorflow/c:tf_status", - "//tensorflow/c:tf_tensor", - "//tensorflow/core:framework", - "//tensorflow/core:lib", - ], -) - - tf_gen_op_libs( op_lib_names = ["bitcast"], deps = [ @@ -50,17 +35,6 @@ tf_gen_op_libs( ], ) -tf_gen_op_libs( - op_lib_names = ["summary"], - deps = [ - "//tensorflow/c:ops", - "//tensorflow/c:tf_datatype", - "//tensorflow/c:tf_status", - "//tensorflow/c:tf_tensor", - "//tensorflow/core:lib", - ], -) - tf_cc_test( name = "bitcast_op_test", srcs = ["bitcast_op_test.cc"], @@ -74,19 +48,6 @@ tf_cc_test( ], ) -tf_cc_test( - name = "summary_op_test", - srcs = ["summary_op_test.cc"], - deps = [ - ":summary_op", - ":summary_op_lib", - "//tensorflow/core:framework", - "//tensorflow/core:protos_all_cc", - "//tensorflow/core:test", - "//tensorflow/core:test_main", - "//tensorflow/core:testlib", - ], -) # Changes to the Android srcs here should be replicated in # tensorflow/contrib/makefile/tf_op_files.txt. # diff --git a/tensorflow/c/kernels/diff.patch b/tensorflow/c/kernels/diff.patch deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tensorflow/c/kernels/ops/summary.cc b/tensorflow/c/kernels/ops/summary.cc deleted file mode 100644 index 550a663d006..00000000000 --- a/tensorflow/c/kernels/ops/summary.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include -#include - -#include "tensorflow/c/ops.h" -#include "tensorflow/core/framework/selective_registration.h" -#include "tensorflow/core/platform/logging.h" -#include "tensorflow/core/platform/macros.h" - - -static void TF_ScalarSummary_shape_inference_fn(TF_ShapeInferenceContext* ctx, - TF_Status* status) { - TF_ShapeHandle* result = TF_NewShapeHandle(); - // TODO: what to do in the case of unknown input shape? - if (TF_GetCode(status) == TF_OK && - !TF_ShapeInferenceContextRankKnown(ctx, result)) { - TF_ShapeInferenceContextSetUnknownShape(ctx, status); - CHECK_EQ(TF_OK, TF_GetCode(status)) - << "Error while setting unknown shape function"; - TF_DeleteShapeHandle(result); - return; - } - // make shape handle a scalar value (empty shape) - if (TF_GetCode(status) == TF_OK) { - TF_ShapeInferenceContextSetOutput(ctx, 0, result, status); - CHECK_EQ(TF_OK, TF_GetCode(status)) - << "Error while setting shape function"; - } - TF_DeleteShapeHandle(result); -} - -void Register_ScalarSummaryOp() { - TF_Status* status = TF_NewStatus(); - - TF_OpDefinitionBuilder* op_builder = TF_NewOpDefinitionBuilder("SummaryScalar"); - TF_OpDefinitionBuilderAddInput(op_builder, "tags: string"); - TF_OpDefinitionBuilderAddInput(op_builder, "values: T"); - TF_OpDefinitionBuilderAddOutput(op_builder, "summary: string"); - TF_OpDefinitionBuilderAddAttr( - op_builder, - "T: realnumbertype"); - TF_OpDefinitionBuilderSetShapeInferenceFunction(op_builder, - &TF_ScalarSummary_shape_inference_fn); - - TF_RegisterOpDefinition(op_builder, status); - CHECK_EQ(TF_GetCode(status), TF_OK) - << "TF_ScalarSummary op registration failed: " << TF_Message(status); - TF_DeleteStatus(status); -} - -TF_ATTRIBUTE_UNUSED static bool SummaryScalarOpRegistered = []() { - if (SHOULD_REGISTER_OP("SummaryScalar")) { - Register_ScalarSummaryOp(); - } - return true; -}(); From 953a8d99a4bae4fd74b32aa71ae3bca3b18dae84 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 24 Jul 2020 21:09:37 +0000 Subject: [PATCH 14/27] clean up --- tensorflow/c/kernels/summary_op.cc | 152 -------------------- tensorflow/c/kernels/summary_op_test.cc | 177 ------------------------ tensorflow/c/kernels_test.cc | 1 - tensorflow/c/tf_tensor.h | 5 - tensorflow/c/tf_tensor_internal.h | 3 - 5 files changed, 338 deletions(-) delete mode 100644 tensorflow/c/kernels/summary_op.cc delete mode 100644 tensorflow/c/kernels/summary_op_test.cc diff --git a/tensorflow/c/kernels/summary_op.cc b/tensorflow/c/kernels/summary_op.cc deleted file mode 100644 index 002de6fb6e8..00000000000 --- a/tensorflow/c/kernels/summary_op.cc +++ /dev/null @@ -1,152 +0,0 @@ - -/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include - -#include "tensorflow/c/kernels.h" -#include "tensorflow/c/ops.h" -#include "tensorflow/c/tf_tensor.h" -#include "tensorflow/core/framework/common_shape_fns.h" -#include "tensorflow/core/framework/op.h" -#include "tensorflow/core/framework/selective_registration.h" -#include "tensorflow/core/framework/shape_inference.h" -#include "tensorflow/core/platform/macros.h" -#include "tensorflow/core/framework/summary.pb.h" -#include "tensorflow/core/platform/protobuf.h" -#include "tensorflow/core/framework/register_types.h" - -#include "tensorflow/core/framework/types.h" -#include - -// TODO: Copy over Summary Scalar Op Doc - -static void* SummaryScalarOp_Create(TF_OpKernelConstruction* ctx) { - // TODO: replace with a void* pointer type later - void* ptr; - return ptr; -} - -static void SummaryScalarOp_Delete(void* kernel) { - return; -} - -bool IsSameSize(TF_Tensor* tensor1, TF_Tensor* tensor2){ - if (TF_NumDims(tensor1) != TF_NumDims(tensor2)){ - return false; - } - for(int d = 0; d < TF_NumDims(tensor1); d++){ - if (TF_Dim(tensor1, d) != TF_Dim(tensor2, d)){ - return false; - } - } - return true; -} - -template -static void SummaryScalarOp_Compute(void* kernel, TF_OpKernelContext* ctx) { - TF_Tensor* tags; - TF_Tensor* values; - TF_Status* status = TF_NewStatus(); - TF_GetInput(ctx, 0, &tags, status); - if (TF_GetCode(status) == TF_OK){ - TF_GetInput(ctx, 1, &values, status); - } - - if (TF_GetCode(status) == TF_OK) { - if (!IsSameSize(tags, values)) { - std::ostringstream err; - err << "tags and values not the same shape: " << TF_ShapeDebugString(tags) - << " != " << TF_ShapeDebugString(values); - TF_SetStatus(status, TF_INVALID_ARGUMENT, err.str().c_str()); - } - } - - // Copy tag and string data into summary protobuf - tensorflow::Summary s; - if (TF_GetCode(status) == TF_OK) { - // Convert tags and values tensor to array to access elements by index - auto tags_array = static_cast(TF_TensorData(tags)); - auto values_array = static_cast(TF_TensorData(values)); - for (int i = 0; i < TF_TensorElementCount(tags); ++i){ - tensorflow::Summary::Value* v = s.add_value(); - v->set_tag(TF_TString_GetDataPointer(&tags_array[i]), - TF_TString_GetSize(&tags_array[i])); - v->set_simple_value(float(values_array[i])); - } - TF_Tensor* summary_tensor = TF_AllocateOutput(ctx, 0, - TF_ExpectedOutputDataType(ctx, 0), nullptr, 0, - sizeof(TF_TString), status); - if (TF_GetCode(status) == TF_OK){ - SerializeToTString(s, static_cast - (TF_TensorData(summary_tensor))); - } - TF_DeleteTensor(summary_tensor); - } - - if (TF_GetCode(status) != TF_OK) { - TF_OpKernelContext_Failure(ctx, status); - } - TF_DeleteStatus(status); - TF_DeleteTensor(tags); -} - -template -void RegisterSummaryScalarOpKernel() { - TF_Status* status = TF_NewStatus(); - { - auto* builder = TF_NewKernelBuilder("SummaryScalar", tensorflow::DEVICE_CPU, - &SummaryScalarOp_Create, &SummaryScalarOp_Compute, - &SummaryScalarOp_Delete); - TF_KernelBuilder_TypeConstraint(builder, "T", static_cast(tensorflow::DataTypeToEnum::v()), status); - CHECK_EQ(TF_OK, TF_GetCode(status)) - << "Error while adding type constraint"; - TF_RegisterKernelBuilder("SummaryScalarOp", builder, status); - CHECK_EQ(TF_OK, TF_GetCode(status)) - << "Error while registering Summary Scalar kernel"; - } -// #if GOOGLE_CUDA -// { -// auto* builder = TF_NewKernelBuilder("SummaryScalar", tensorflow::DEVICE_GPU, -// &SummaryScalarOp_Create, &SummaryScalarOp_Compute, -// &SummaryScalarOp_Delete); -// TF_RegisterKernelBuilder("SummaryScalar", builder, status); -// CHECK_EQ(TF_OK, TF_GetCode(status)) -// << "Error while registering CUDA SummaryScalar kernel"; -// } -// #endif - - TF_DeleteStatus(status); -} - -// A dummy static variable initialized by a lambda whose side-effect is to -// register the bitcast kernel. - - -TF_ATTRIBUTE_UNUSED static bool IsSummaryScalarOpKernelRegistered = []() { - if (SHOULD_REGISTER_OP_KERNEL("SummaryScalarOp")) { - RegisterSummaryScalarOpKernel(); - RegisterSummaryScalarOpKernel(); - RegisterSummaryScalarOpKernel(); - RegisterSummaryScalarOpKernel(); - RegisterSummaryScalarOpKernel(); - RegisterSummaryScalarOpKernel(); - RegisterSummaryScalarOpKernel(); - RegisterSummaryScalarOpKernel(); - RegisterSummaryScalarOpKernel(); - } - return true; -}(); - diff --git a/tensorflow/c/kernels/summary_op_test.cc b/tensorflow/c/kernels/summary_op_test.cc deleted file mode 100644 index afc818fb7b5..00000000000 --- a/tensorflow/c/kernels/summary_op_test.cc +++ /dev/null @@ -1,177 +0,0 @@ -/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "tensorflow/core/framework/attr_value.pb.h" -#include "tensorflow/core/framework/attr_value_util.h" -#include "tensorflow/core/framework/fake_input.h" -#include "tensorflow/core/framework/node_def.pb.h" -#include "tensorflow/core/framework/node_def_builder.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/framework/shape_inference.h" -#include "tensorflow/core/platform/test.h" - -#include "tensorflow/core/framework/summary.pb.h" -#include "tensorflow/core/platform/protobuf.h" -#include "tensorflow/c/tf_tensor.h" -#include "tensorflow/c/tf_tensor_internal.h" - -#include -#include -#include -namespace tensorflow { -namespace { - -class DummyDevice : public DeviceBase { - public: - explicit DummyDevice(Env* env) : DeviceBase(env) {} - Allocator* GetAllocator(AllocatorAttributes /*attr*/) override { - return cpu_allocator(); - } -}; - -// Helper for comparing ouput and expected output -static void EXPECT_SummaryMatches(const Summary& actual, - const string& expected_str) { - Summary expected; - (protobuf::TextFormat::ParseFromString(expected_str, &expected)); - EXPECT_EQ(expected.DebugString(), actual.DebugString()); -} - - -void TestScalarSummaryOp(Tensor* tags, Tensor* values, string expected_summary, - error::Code expected_code) { - // initialize node used to fetch OpKernel - Status status; - NodeDef def; - def.set_op("SummaryScalar"); - def.set_device(DEVICE_CPU); - AttrValue valuesTypeAttr; - SetAttrValue(values->dtype(), &valuesTypeAttr); - (*def.mutable_attr())["T"] = valuesTypeAttr; - def.add_input( - strings::StrCat("input1: ", DataTypeString(tags->dtype()))); - def.add_input( - strings::StrCat("input2: ", DataTypeString(values->dtype()))); - - std::unique_ptr kernel = - CreateOpKernel(DeviceType(DEVICE_CPU), nullptr, nullptr, def, 1, &status); - ASSERT_TRUE(status.ok()) << status.ToString(); - - // initialize OpKernel parameters - OpKernelContext::Params params; - DummyDevice dummy_device(nullptr); - params.device = &dummy_device; - params.op_kernel = kernel.get(); - gtl::InlinedVector inputs; - inputs.emplace_back(tags); - inputs.emplace_back(values); - params.inputs = &inputs; - OpKernelContext ctx(¶ms, 1); - AllocatorAttributes alloc_attrs; - std::vector output_alloc_attrs({alloc_attrs}); - params.output_attr_array = output_alloc_attrs.data(); - kernel->Compute(&ctx); - ASSERT_EQ(expected_code, ctx.status().code()); - if (expected_code == error::OK){ - Summary summary; - ParseProtoUnlimited(&summary, ctx.mutable_output(0)->scalar()()); - EXPECT_SummaryMatches(summary, expected_summary); - } -} - -TEST(ScalarSummaryOpTest, SimpleFloat) { - int vectorSize = 3; - Tensor tags(DT_STRING, {vectorSize}); - Tensor values(DT_FLOAT, {vectorSize}); - tags.vec()(0) = "tag1"; - tags.vec()(1) = "tag2"; - tags.vec()(2) = "tag3"; - values.vec()(0) = 1.0f; - values.vec()(1) = -0.73f; - values.vec()(2) = 10000.0f; - TestScalarSummaryOp(&tags, &values, R"( - value { tag: 'tag1' simple_value: 1.0 } - value { tag: 'tag2' simple_value: -0.73} - value { tag: 'tag3' simple_value: 10000.0})", error::OK); -} - -TEST(ScalarSummaryOpTest, SimpleDouble) { - int vectorSize = 3; - Tensor tags(DT_STRING, {vectorSize}); - Tensor values(DT_DOUBLE, {vectorSize}); - tags.vec()(0) = "tag1"; - tags.vec()(1) = "tag2"; - tags.vec()(2) = "tag3"; - values.vec()(0) = 1.0; - values.vec()(1) = -0.73; - values.vec()(2) = 10000.0; - TestScalarSummaryOp(&tags, &values, R"( - value { tag: 'tag1' simple_value: 1.0 } - value { tag: 'tag2' simple_value: -0.73} - value { tag: 'tag3' simple_value: 10000.0})", error::OK); -} - -TEST(ScalarSummaryOpTest, SimpleHalf) { - int vectorSize = 3; - Tensor tags(DT_STRING, {vectorSize}); - Tensor values(DT_HALF, {vectorSize}); - tags.vec()(0) = "tag1"; - tags.vec()(1) = "tag2"; - tags.vec()(2) = "tag3"; - values.vec()(0) = static_cast(1.0); - values.vec()(1) = static_cast(-2.0); - values.vec()(2) = static_cast(10000.0); - TestScalarSummaryOp(&tags, &values, R"( - value { tag: 'tag1' simple_value: 1.0 } - value { tag: 'tag2' simple_value: -2.0} - value { tag: 'tag3' simple_value: 10000.0})", error::OK); -} - -TEST(ScalarSummaryOpTest, Error_WrongDimsTags) { - int vectorSize = 3; - Tensor tags(DT_STRING, {2, 1}); - Tensor values(DT_FLOAT, {2}); - tags.matrix()(0, 0) = "tag1"; - tags.matrix()(1, 0) = "tag2"; - values.vec()(0) = 1.0f; - values.vec()(1) = -2.0f; - TestScalarSummaryOp(&tags, &values, R"()", error::INVALID_ARGUMENT); -} - -TEST(ScalarSummaryOpTest, Error_WrongValuesTags) { - Tensor tags(DT_STRING, {2}); - Tensor values(DT_FLOAT, {2, 1}); - tags.vec()(0) = "tag1"; - tags.vec()(1) = "tag2"; - values.matrix()(0, 0) = 1.0f; - values.matrix()(1, 0) = -2.0f; - TestScalarSummaryOp(&tags, &values, R"()", error::INVALID_ARGUMENT); -} - -TEST(ScalarSummaryOpTest, IsRegistered){ - const OpRegistrationData* reg; - TF_CHECK_OK(OpRegistry::Global()->LookUp("SummaryScalar", ®)); -} - - - -PartialTensorShape S(std::initializer_list dims) { - return PartialTensorShape(dims); -} - - - -} // namespace -} // namespace tensorflow diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 4c925402cb7..e2eef11db0e 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -568,5 +568,4 @@ void set_tensor_data(TF_Tensor* tensor, T* values, size_t tensor_size_bytes, memcpy(data, values, tensor_size_bytes); #endif } - } // namespace tensorflow \ No newline at end of file diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index d8d8155e8cd..91263fb3b7f 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -22,9 +22,6 @@ limitations under the License. #include "tensorflow/c/tf_datatype.h" #include "tensorflow/c/tf_status.h" -#include -#include - // Macro to control visibility of exported symbols in the shared library (.so, // .dylib, .dll). // This duplicates the TF_EXPORT macro definition in @@ -172,8 +169,6 @@ TF_CAPI_EXPORT extern void TF_TensorBitcastFrom(const TF_Tensor* from, // Returns bool iff this tensor is aligned. TF_CAPI_EXPORT extern bool TF_TensorIsAligned(const TF_Tensor*); -TF_CAPI_EXPORT extern std::string TF_ShapeDebugString(const TF_Tensor*); - #ifdef __cplusplus } /* end extern "C" */ #endif diff --git a/tensorflow/c/tf_tensor_internal.h b/tensorflow/c/tf_tensor_internal.h index b3f44c71245..7a896dc5d11 100644 --- a/tensorflow/c/tf_tensor_internal.h +++ b/tensorflow/c/tf_tensor_internal.h @@ -24,8 +24,6 @@ limitations under the License. #include "tensorflow/core/framework/tensor.h" #include "tensorflow/core/framework/tensor_shape.h" #include "tensorflow/core/platform/casts.h" -#include -#include // Internal structures used by the C API. These are likely to change and should // not be depended on. @@ -106,7 +104,6 @@ class TensorInterface : public AbstractTensorInterface { void* Data() const override; bool IsAligned() const override; bool CanMove() const override; - std::string ShapeDebugString() const; Status ToTensor(tensorflow::Tensor* dst) const; Status BitcastFrom(const TensorInterface& from, DataType type, From be5f945a62daa9d90df2a7098cd4b156a001e4c4 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 24 Jul 2020 21:23:41 +0000 Subject: [PATCH 15/27] clean up for cleaner merge --- tensorflow/c/tf_tensor.cc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tensorflow/c/tf_tensor.cc b/tensorflow/c/tf_tensor.cc index 39f0176c0bf..0feb986ce44 100644 --- a/tensorflow/c/tf_tensor.cc +++ b/tensorflow/c/tf_tensor.cc @@ -28,8 +28,6 @@ limitations under the License. #include "tensorflow/core/framework/types.pb.h" #include "tensorflow/core/lib/core/coding.h" #include "tensorflow/core/platform/casts.h" -#include -#include using tensorflow::Status; using tensorflow::Tensor; @@ -182,11 +180,6 @@ void TF_TensorBitcastFrom(const TF_Tensor* from, TF_DataType type, Set_TF_Status_from_Status(status, cc_status); } -std::string TF_ShapeDebugString(const TF_Tensor* t){ - return tensorflow::down_cast(t->tensor) - ->ShapeDebugString(); -} - namespace tensorflow { void TensorInterface::Release() { delete this; } @@ -232,10 +225,6 @@ Status TensorInterface::BitcastFrom(const TensorInterface& from, DataType type, return tensor_.BitcastFrom(from.tensor_, type, s); } -std::string TensorInterface::ShapeDebugString() const { - return tensor_.shape().DebugString(); -} - } // namespace tensorflow // -------------------------------------------------------------------------- @@ -267,7 +256,6 @@ static TF_Tensor* EmptyTensor(TF_DataType dtype, namespace tensorflow { // Non-static for testing. - TF_Tensor* TF_TensorFromTensor(const tensorflow::Tensor& src, Status* status) { *status = tensorflow::Status::OK(); if (!src.IsInitialized()) { @@ -328,10 +316,8 @@ Status TensorInterface::ToTensor(tensorflow::Tensor* dst) const { return Status::OK(); } - bool TensorInterface::IsAligned() const { return tensor_.IsAligned(); } } // namespace tensorflow bool TF_TensorIsAligned(const TF_Tensor* t) { return t->tensor->IsAligned(); } - From e31572f0adbd24a061d8dc6475bca93367cc9637 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Fri, 24 Jul 2020 22:11:06 +0000 Subject: [PATCH 16/27] incorporate previous changes to allocate_temp --- tensorflow/c/kernels.cc | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 5bd3989e66c..d89c222568f 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -281,22 +281,25 @@ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, TF_SetStatus(status, TF_OK, ""); tensorflow::TensorShape shape; for (int i = 0; i < num_dims; ++i) { - shape.AddDim(dims[i]); + shape.AddDim(dims[i]); } tensorflow::AllocatorAttributes allocator_attr; if (attributes.on_host) { allocator_attr.set_on_host(true); } tensorflow::Status s; - tensorflow::Tensor tensor_temp; - TF_Tensor* tf_tensor_temp; - s = cc_ctx->allocate_temp(static_cast(dtype), shape, + tensorflow::Tensor tensor; + TF_Tensor* tf_tensor; + s = cc_ctx->allocate_temp(static_cast(dtype), shape, &tensor_temp, allocator_attr); - if (s.ok()) { - tf_tensor_temp = TF_TensorFromTensor(tensor_temp, &s); + if (!s.ok()) { + ::tensorflow::Set_TF_Status_fromStatus(status, s); + return nullptr; } - if (s.ok()) { - ::tensorflow::Set_TF_Status_from_Status(status, s); - return tf_tensor_temp; - } + tf_tensor = TF_TensorFromTensor(tensor, &s); + if (!s.ok()) { + ::tensorflow::Set_TF_Status_from_Status(status, s); + return nullptr; + } + return tf_tensor; } From 5d12611c3b69fd159321e465873f8cfd012f209e Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Mon, 27 Jul 2020 22:37:42 +0000 Subject: [PATCH 17/27] added device memory test for allocate_temp --- tensorflow/c/kernels.cc | 4 ++-- tensorflow/c/kernels_test.cc | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index d89c222568f..b1d302ce4b3 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -291,9 +291,9 @@ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, tensorflow::Tensor tensor; TF_Tensor* tf_tensor; s = cc_ctx->allocate_temp(static_cast(dtype), shape, - &tensor_temp, allocator_attr); + &tensor, allocator_attr); if (!s.ok()) { - ::tensorflow::Set_TF_Status_fromStatus(status, s); + ::tensorflow::Set_TF_Status_from_Status(status, s); return nullptr; } tf_tensor = TF_TensorFromTensor(tensor, &s); diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index e2eef11db0e..e9a5fa1f3ee 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -547,6 +547,40 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { output->DebugString(100)); } +REGISTER_OP("AllocateTempOpDeviceMemory").Output("output1: float"); + +TEST_F(DeviceKernelOpTest, TestAllocateTempOpDeviceMemory) { + auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { + // Allocate scalar TF_Tensor + TF_Status* s = TF_NewStatus(); + int64_t dim = 1; + TF_AllocatorAttributes alloc_attrs; + alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; + alloc_attrs.on_host = 0; + TF_Tensor* output = TF_AllocateTemp( + /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, + /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); + size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT); + EXPECT_EQ(TF_OK, TF_GetCode(s)); + + // Set TF_Tensor value to 3 + float values[1] = {3.0f}; + set_tensor_data(output, values, tensor_size_bytes, ctx); + validate_tensor(output, &dim, 1, TF_FLOAT); + TF_SetOutput(ctx, 0, output, s); + TF_DeleteStatus(s); + TF_DeleteTensor(output); + }; + + SetupOp("AllocateTempOpDeviceMemory", "AllocateTempOpDeviceMemory", + my_compute_func); + + TF_ASSERT_OK(RunOpKernel()); + Tensor* output = GetOutput(0); + EXPECT_EQ("Tensor", + output->DebugString(100)); +} + void validate_tensor(TF_Tensor* tensor, int64_t* dims, int64_t num_dims, TF_DataType dtype){ EXPECT_EQ(TF_FLOAT, TF_TensorType(tensor)); From 3e2145b3a028f8ea2ed5ca76dd28cc5d96bd09ee Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Tue, 28 Jul 2020 19:30:45 +0000 Subject: [PATCH 18/27] added support for device memory test --- tensorflow/c/kernels_test.cc | 42 +++++++----------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index e9a5fa1f3ee..0c7cd76fc37 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -494,7 +494,11 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempEmpty) { int64_t dim = 0; TF_AllocatorAttributes alloc_attrs; alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; +#if GOOGLE_CUDA + alloc_attrs.on_host = 0; +#else alloc_attrs.on_host = 1; +#endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); @@ -523,7 +527,11 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { int64_t dim[2] = {2, 3}; TF_AllocatorAttributes alloc_attrs; alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; +#if GOOGLE_CUDA + alloc_attrs.on_host = 0; +#else alloc_attrs.on_host = 1; +#endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/dim, /*num_dims=*/2, /*allocator_attributes*/ alloc_attrs, s); @@ -545,40 +553,6 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { Tensor* output = GetOutput(0); EXPECT_EQ("Tensor", output->DebugString(100)); -} - -REGISTER_OP("AllocateTempOpDeviceMemory").Output("output1: float"); - -TEST_F(DeviceKernelOpTest, TestAllocateTempOpDeviceMemory) { - auto my_compute_func = [](void* kernel, TF_OpKernelContext* ctx) { - // Allocate scalar TF_Tensor - TF_Status* s = TF_NewStatus(); - int64_t dim = 1; - TF_AllocatorAttributes alloc_attrs; - alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; - alloc_attrs.on_host = 0; - TF_Tensor* output = TF_AllocateTemp( - /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); - size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT); - EXPECT_EQ(TF_OK, TF_GetCode(s)); - - // Set TF_Tensor value to 3 - float values[1] = {3.0f}; - set_tensor_data(output, values, tensor_size_bytes, ctx); - validate_tensor(output, &dim, 1, TF_FLOAT); - TF_SetOutput(ctx, 0, output, s); - TF_DeleteStatus(s); - TF_DeleteTensor(output); - }; - - SetupOp("AllocateTempOpDeviceMemory", "AllocateTempOpDeviceMemory", - my_compute_func); - - TF_ASSERT_OK(RunOpKernel()); - Tensor* output = GetOutput(0); - EXPECT_EQ("Tensor", - output->DebugString(100)); } void validate_tensor(TF_Tensor* tensor, int64_t* dims, int64_t num_dims, From 864dd7d618ddfbb5cd88d9f0b5e349203a1ba1fa Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Wed, 29 Jul 2020 01:42:49 +0000 Subject: [PATCH 19/27] fixed one failing test --- tensorflow/c/kernels_test.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 0c7cd76fc37..6a13473970c 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -461,7 +461,11 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { int64_t dim = 1; TF_AllocatorAttributes alloc_attrs; alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; +#if GOOGLE_CUDA + alloc_attrs.on_host = 0; +#else alloc_attrs.on_host = 1; +#endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); From ead0e64bb5efb1a9e7e46a7501dcee0919fdb5fc Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Thu, 30 Jul 2020 18:32:19 +0000 Subject: [PATCH 20/27] clean up only --- tensorflow/c/kernels_test.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 6a13473970c..ccf9dae11d7 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -543,7 +543,6 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { validate_tensor(output, dim, 2, TF_FLOAT); // Set TF_Tensor values to [1 2 3 4 5 6] - void* data = TF_TensorData(output); float values[6] = {1, 2, 3, 4, 5, 6}; set_tensor_data(output, values, tensor_size_bytes, ctx); TF_SetOutput(ctx, 0, output, s); From eed154ca65961d14b99f207ea57f8dd421bb9df3 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Mon, 3 Aug 2020 23:42:27 +0000 Subject: [PATCH 21/27] changed TF_AllocatorAttributes usage to pass by pointer --- tensorflow/c/kernels.cc | 14 ++++++-------- tensorflow/c/kernels.h | 2 +- tensorflow/c/kernels_test.cc | 6 +++--- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index b2200f7c9af..6d9d7d57517 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -283,23 +283,21 @@ TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int index, TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, int64_t* dims, int num_dims, - TF_AllocatorAttributes attributes, + TF_AllocatorAttributes* attributes, TF_Status* status) { auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); TF_SetStatus(status, TF_OK, ""); - tensorflow::TensorShape shape; - for (int i = 0; i < num_dims; ++i) { - shape.AddDim(dims[i]); - } + tensorflow::gtl::ArraySlice dimarray( + reinterpret_cast(dims), num_dims); tensorflow::AllocatorAttributes allocator_attr; - if (attributes.on_host) { + if (attributes->on_host) { allocator_attr.set_on_host(true); } tensorflow::Status s; tensorflow::Tensor tensor; TF_Tensor* tf_tensor; - s = cc_ctx->allocate_temp(static_cast(dtype), shape, - &tensor, allocator_attr); + s = cc_ctx->allocate_temp(static_cast(dtype), + tensorflow::TensorShape(dimarray), &tensor, allocator_attr); if (!s.ok()) { ::tensorflow::Set_TF_Status_from_Status(status, s); return nullptr; diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index 178e1a29267..d6a7070de06 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -206,7 +206,7 @@ TF_CAPI_EXPORT TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, // num_dims must equal the size of array dims TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, - TF_DataType dtype, int64_t* dims, int num_dims, TF_AllocatorAttributes + TF_DataType dtype, int64_t* dims, int num_dims, TF_AllocatorAttributes* alloc_attrs, TF_Status* status); diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 82027ffd1e0..708c39690a8 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -476,7 +476,7 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); + /*num_dims=*/1, /*allocator_attributes*/ &alloc_attrs, s); size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); @@ -513,7 +513,7 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempEmpty) { #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); + /*num_dims=*/1, /*allocator_attributes*/ &alloc_attrs, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); TF_SetOutput(ctx, 0, output, s); @@ -546,7 +546,7 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/dim, - /*num_dims=*/2, /*allocator_attributes*/ alloc_attrs, s); + /*num_dims=*/2, /*allocator_attributes*/ &alloc_attrs, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, dim, 2, TF_FLOAT); From 8ef70baf379615028d34395e8d44865e3df3828f Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Tue, 4 Aug 2020 20:25:26 +0000 Subject: [PATCH 22/27] moved TF_OFFSET_OF_END to c_api_macros --- tensorflow/c/BUILD | 1 + tensorflow/c/c_api_macros.h | 7 +++++++ tensorflow/c/tf_tensor.h | 8 +------- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tensorflow/c/BUILD b/tensorflow/c/BUILD index 410fc22069f..4a0ab232200 100644 --- a/tensorflow/c/BUILD +++ b/tensorflow/c/BUILD @@ -299,6 +299,7 @@ cc_library( hdrs = ["tf_tensor.h"], visibility = ["//visibility:public"], deps = [ + ":c_api_macros", ":tensor_interface", ":tf_datatype", ":tf_status", diff --git a/tensorflow/c/c_api_macros.h b/tensorflow/c/c_api_macros.h index 85c9507db87..ce24e4d8cbd 100644 --- a/tensorflow/c/c_api_macros.h +++ b/tensorflow/c/c_api_macros.h @@ -30,4 +30,11 @@ limitations under the License. #endif // _WIN32 #endif // SWIG +// Macro used to calculate struct size for maintaining ABI stability across +// different struct implementations. +#ifndef TF_OFFSET_OF_END +#define TF_OFFSET_OF_END(TYPE, MEMBER) (offsetof(TYPE, MEMBER) + \ + sizeof(((TYPE *)0)->MEMBER)) +#endif // TF_OFFSET_OF_END + #endif // TENSORFLOW_C_C_API_MACROS_H_ diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index 91263fb3b7f..ced57df77d4 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -19,6 +19,7 @@ limitations under the License. #include #include +#include "tensorflow/c/c_api_macros.h" #include "tensorflow/c/tf_datatype.h" #include "tensorflow/c/tf_status.h" @@ -45,13 +46,6 @@ limitations under the License. extern "C" { #endif -// Macro used to calculate struct size for maintaining ABI stability across -// different struct implementations. -#ifndef TF_OFFSET_OF_END -#define TF_OFFSET_OF_END(TYPE, MEMBER) (offsetof(TYPE, MEMBER) + \ - sizeof(((TYPE *)0)->MEMBER)) -#endif // TF_OFFSET_OF_END - // Allocator Attributes used for tensor allocation. typedef struct TF_AllocatorAttributes { size_t struct_size; From 54b76dc588d28643fbfd0a297870d79326b11abb Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Tue, 4 Aug 2020 22:08:35 +0000 Subject: [PATCH 23/27] switched from allocator attributes struct to opaque pointer --- tensorflow/c/kernels.cc | 6 +----- tensorflow/c/kernels.h | 1 - tensorflow/c/kernels_test.cc | 36 +++++++++++++------------------ tensorflow/c/tf_tensor.cc | 17 +++++++++++++++ tensorflow/c/tf_tensor.h | 22 +++++++++---------- tensorflow/c/tf_tensor_internal.h | 5 +++++ 6 files changed, 49 insertions(+), 38 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 6d9d7d57517..096c8e41812 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -289,15 +289,11 @@ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, TF_SetStatus(status, TF_OK, ""); tensorflow::gtl::ArraySlice dimarray( reinterpret_cast(dims), num_dims); - tensorflow::AllocatorAttributes allocator_attr; - if (attributes->on_host) { - allocator_attr.set_on_host(true); - } tensorflow::Status s; tensorflow::Tensor tensor; TF_Tensor* tf_tensor; s = cc_ctx->allocate_temp(static_cast(dtype), - tensorflow::TensorShape(dimarray), &tensor, allocator_attr); + tensorflow::TensorShape(dimarray), &tensor, attributes->alloc_attrs); if (!s.ok()) { ::tensorflow::Set_TF_Status_from_Status(status, s); return nullptr; diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index d6a7070de06..ee865613b6e 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -209,7 +209,6 @@ TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, int64_t* dims, int num_dims, TF_AllocatorAttributes* alloc_attrs, TF_Status* status); - #ifdef __cplusplus } /* end extern "C" */ #endif diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 708c39690a8..5239274a2ce 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -467,16 +467,13 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { // Allocate scalar TF_Tensor TF_Status* s = TF_NewStatus(); int64_t dim = 1; - TF_AllocatorAttributes alloc_attrs; - alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; -#if GOOGLE_CUDA - alloc_attrs.on_host = 0; -#else - alloc_attrs.on_host = 1; + TF_AllocatorAttributes* alloc_attrs = TF_NewAllocatorAttributes(); +#if !GOOGLE_CUDA + TF_AllocatorAttributesSetOnHost(alloc_attrs); #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, /*allocator_attributes*/ &alloc_attrs, s); + /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); @@ -487,6 +484,7 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { TF_SetOutput(ctx, 0, output, s); TF_DeleteStatus(s); TF_DeleteTensor(output); + TF_DeleteAllocatorAttributes(alloc_attrs); }; SetupOp("AllocateTempOp1", "AllocateTemp1", my_compute_func); @@ -504,21 +502,19 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempEmpty) { TF_Status* s = TF_NewStatus(); // Allocate empty TF_Tensor int64_t dim = 0; - TF_AllocatorAttributes alloc_attrs; - alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; -#if GOOGLE_CUDA - alloc_attrs.on_host = 0; -#else - alloc_attrs.on_host = 1; + TF_AllocatorAttributes* alloc_attrs = TF_NewAllocatorAttributes(); +#if !GOOGLE_CUDA + TF_AllocatorAttributesSetOnHost(alloc_attrs); #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, /*allocator_attributes*/ &alloc_attrs, s); + /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); TF_SetOutput(ctx, 0, output, s); TF_DeleteStatus(s); TF_DeleteTensor(output); + TF_DeleteAllocatorAttributes(alloc_attrs); }; SetupOp("AllocateTempOp0", "AllocateTemp0", my_compute_func); @@ -537,16 +533,13 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { size_t tensor_size_bytes = 6 * TF_DataTypeSize(TF_FLOAT); // Allocate 2x3 TF_Tensor int64_t dim[2] = {2, 3}; - TF_AllocatorAttributes alloc_attrs; - alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; -#if GOOGLE_CUDA - alloc_attrs.on_host = 0; -#else - alloc_attrs.on_host = 1; + TF_AllocatorAttributes* alloc_attrs = TF_NewAllocatorAttributes(); +#if !GOOGLE_CUDA + TF_AllocatorAttributesSetOnHost(alloc_attrs); #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/dim, - /*num_dims=*/2, /*allocator_attributes*/ &alloc_attrs, s); + /*num_dims=*/2, /*allocator_attributes*/ alloc_attrs, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, dim, 2, TF_FLOAT); @@ -556,6 +549,7 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { TF_SetOutput(ctx, 0, output, s); TF_DeleteStatus(s); TF_DeleteTensor(output); + TF_DeleteAllocatorAttributes(alloc_attrs); }; SetupOp("AllocateTempOp2x3", "AllocateTempOp2x3", my_compute_func); diff --git a/tensorflow/c/tf_tensor.cc b/tensorflow/c/tf_tensor.cc index 0feb986ce44..12405939bfc 100644 --- a/tensorflow/c/tf_tensor.cc +++ b/tensorflow/c/tf_tensor.cc @@ -321,3 +321,20 @@ bool TensorInterface::IsAligned() const { return tensor_.IsAligned(); } } // namespace tensorflow bool TF_TensorIsAligned(const TF_Tensor* t) { return t->tensor->IsAligned(); } + +TF_AllocatorAttributes* TF_NewAllocatorAttributes() { + return new TF_AllocatorAttributes{tensorflow::AllocatorAttributes()}; +} + +void TF_AllocatorAttributesSetOnHost(TF_AllocatorAttributes* tf_alloc_attrs) { + tf_alloc_attrs->alloc_attrs.set_on_host(true); +} + +void TF_DeleteAllocatorAttributes(TF_AllocatorAttributes* tf_alloc_attrs) { + if (tf_alloc_attrs == nullptr) { + return; + } + else { + delete tf_alloc_attrs; + } +} diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index ced57df77d4..9a043ce0538 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -46,17 +46,6 @@ limitations under the License. extern "C" { #endif -// Allocator Attributes used for tensor allocation. -typedef struct TF_AllocatorAttributes { - size_t struct_size; - // Set boolean to 1 for CPU allocation, else 0. - unsigned char on_host; -} TF_AllocatorAttributes; - - -#define TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE \ - TF_OFFSET_OF_END(TF_AllocatorAttributes, on_host) - // -------------------------------------------------------------------------- // TF_Tensor holds a multi-dimensional array of elements of a single data type. // For all types other than TF_STRING, the data buffer stores elements @@ -163,6 +152,17 @@ TF_CAPI_EXPORT extern void TF_TensorBitcastFrom(const TF_Tensor* from, // Returns bool iff this tensor is aligned. TF_CAPI_EXPORT extern bool TF_TensorIsAligned(const TF_Tensor*); +// Allocator Attributes used for tensor allocation. +typedef struct TF_AllocatorAttributes TF_AllocatorAttributes; + +TF_CAPI_EXPORT extern TF_AllocatorAttributes* TF_NewAllocatorAttributes(); + +TF_CAPI_EXPORT extern void TF_AllocatorAttributesSetOnHost( + TF_AllocatorAttributes* tf_alloc_attrs); + +TF_CAPI_EXPORT extern void TF_DeleteAllocatorAttributes( + TF_AllocatorAttributes* tf_alloc_attrs); + #ifdef __cplusplus } /* end extern "C" */ #endif diff --git a/tensorflow/c/tf_tensor_internal.h b/tensorflow/c/tf_tensor_internal.h index 7a896dc5d11..71cac0afeb1 100644 --- a/tensorflow/c/tf_tensor_internal.h +++ b/tensorflow/c/tf_tensor_internal.h @@ -23,6 +23,7 @@ limitations under the License. #include "tensorflow/core/framework/allocation_description.pb.h" #include "tensorflow/core/framework/tensor.h" #include "tensorflow/core/framework/tensor_shape.h" +#include "tensorflow/core/framework/allocator.h" #include "tensorflow/core/platform/casts.h" // Internal structures used by the C API. These are likely to change and should @@ -124,4 +125,8 @@ Status TF_TensorToTensor(const TF_Tensor* src, Tensor* dst); TF_Tensor* TF_TensorFromTensor(const Tensor& src, Status* status); } // namespace tensorflow +typedef struct TF_AllocatorAttributes { + tensorflow::AllocatorAttributes alloc_attrs; +} TF_AllocatorAttributes; + #endif // TENSORFLOW_C_TF_TENSOR_INTERNAL_H_ From b6960d8bd1e513aa1915a3064ffa0e248ceff040 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Wed, 5 Aug 2020 19:13:52 +0000 Subject: [PATCH 24/27] Revert "switched from allocator attributes struct to opaque pointer" This reverts commit 54b76dc588d28643fbfd0a297870d79326b11abb. --- tensorflow/c/kernels.cc | 6 +++++- tensorflow/c/kernels.h | 1 + tensorflow/c/kernels_test.cc | 36 ++++++++++++++++++------------- tensorflow/c/tf_tensor.cc | 17 --------------- tensorflow/c/tf_tensor.h | 22 +++++++++---------- tensorflow/c/tf_tensor_internal.h | 5 ----- 6 files changed, 38 insertions(+), 49 deletions(-) diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 096c8e41812..6d9d7d57517 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -289,11 +289,15 @@ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, TF_SetStatus(status, TF_OK, ""); tensorflow::gtl::ArraySlice dimarray( reinterpret_cast(dims), num_dims); + tensorflow::AllocatorAttributes allocator_attr; + if (attributes->on_host) { + allocator_attr.set_on_host(true); + } tensorflow::Status s; tensorflow::Tensor tensor; TF_Tensor* tf_tensor; s = cc_ctx->allocate_temp(static_cast(dtype), - tensorflow::TensorShape(dimarray), &tensor, attributes->alloc_attrs); + tensorflow::TensorShape(dimarray), &tensor, allocator_attr); if (!s.ok()) { ::tensorflow::Set_TF_Status_from_Status(status, s); return nullptr; diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index ee865613b6e..d6a7070de06 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -209,6 +209,7 @@ TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, int64_t* dims, int num_dims, TF_AllocatorAttributes* alloc_attrs, TF_Status* status); + #ifdef __cplusplus } /* end extern "C" */ #endif diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 5239274a2ce..708c39690a8 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -467,13 +467,16 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { // Allocate scalar TF_Tensor TF_Status* s = TF_NewStatus(); int64_t dim = 1; - TF_AllocatorAttributes* alloc_attrs = TF_NewAllocatorAttributes(); -#if !GOOGLE_CUDA - TF_AllocatorAttributesSetOnHost(alloc_attrs); + TF_AllocatorAttributes alloc_attrs; + alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; +#if GOOGLE_CUDA + alloc_attrs.on_host = 0; +#else + alloc_attrs.on_host = 1; #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); + /*num_dims=*/1, /*allocator_attributes*/ &alloc_attrs, s); size_t tensor_size_bytes = TF_DataTypeSize(TF_FLOAT); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); @@ -484,7 +487,6 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSizeOne) { TF_SetOutput(ctx, 0, output, s); TF_DeleteStatus(s); TF_DeleteTensor(output); - TF_DeleteAllocatorAttributes(alloc_attrs); }; SetupOp("AllocateTempOp1", "AllocateTemp1", my_compute_func); @@ -502,19 +504,21 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempEmpty) { TF_Status* s = TF_NewStatus(); // Allocate empty TF_Tensor int64_t dim = 0; - TF_AllocatorAttributes* alloc_attrs = TF_NewAllocatorAttributes(); -#if !GOOGLE_CUDA - TF_AllocatorAttributesSetOnHost(alloc_attrs); + TF_AllocatorAttributes alloc_attrs; + alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; +#if GOOGLE_CUDA + alloc_attrs.on_host = 0; +#else + alloc_attrs.on_host = 1; #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/&dim, - /*num_dims=*/1, /*allocator_attributes*/ alloc_attrs, s); + /*num_dims=*/1, /*allocator_attributes*/ &alloc_attrs, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, &dim, 1, TF_FLOAT); TF_SetOutput(ctx, 0, output, s); TF_DeleteStatus(s); TF_DeleteTensor(output); - TF_DeleteAllocatorAttributes(alloc_attrs); }; SetupOp("AllocateTempOp0", "AllocateTemp0", my_compute_func); @@ -533,13 +537,16 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { size_t tensor_size_bytes = 6 * TF_DataTypeSize(TF_FLOAT); // Allocate 2x3 TF_Tensor int64_t dim[2] = {2, 3}; - TF_AllocatorAttributes* alloc_attrs = TF_NewAllocatorAttributes(); -#if !GOOGLE_CUDA - TF_AllocatorAttributesSetOnHost(alloc_attrs); + TF_AllocatorAttributes alloc_attrs; + alloc_attrs.struct_size = TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE; +#if GOOGLE_CUDA + alloc_attrs.on_host = 0; +#else + alloc_attrs.on_host = 1; #endif TF_Tensor* output = TF_AllocateTemp( /*context=*/ctx, /*dtype=*/TF_FLOAT, /*dims=*/dim, - /*num_dims=*/2, /*allocator_attributes*/ alloc_attrs, s); + /*num_dims=*/2, /*allocator_attributes*/ &alloc_attrs, s); EXPECT_EQ(TF_OK, TF_GetCode(s)); validate_tensor(output, dim, 2, TF_FLOAT); @@ -549,7 +556,6 @@ TEST_F(DeviceKernelOpTest, TestAllocateTempSize2x3) { TF_SetOutput(ctx, 0, output, s); TF_DeleteStatus(s); TF_DeleteTensor(output); - TF_DeleteAllocatorAttributes(alloc_attrs); }; SetupOp("AllocateTempOp2x3", "AllocateTempOp2x3", my_compute_func); diff --git a/tensorflow/c/tf_tensor.cc b/tensorflow/c/tf_tensor.cc index 12405939bfc..0feb986ce44 100644 --- a/tensorflow/c/tf_tensor.cc +++ b/tensorflow/c/tf_tensor.cc @@ -321,20 +321,3 @@ bool TensorInterface::IsAligned() const { return tensor_.IsAligned(); } } // namespace tensorflow bool TF_TensorIsAligned(const TF_Tensor* t) { return t->tensor->IsAligned(); } - -TF_AllocatorAttributes* TF_NewAllocatorAttributes() { - return new TF_AllocatorAttributes{tensorflow::AllocatorAttributes()}; -} - -void TF_AllocatorAttributesSetOnHost(TF_AllocatorAttributes* tf_alloc_attrs) { - tf_alloc_attrs->alloc_attrs.set_on_host(true); -} - -void TF_DeleteAllocatorAttributes(TF_AllocatorAttributes* tf_alloc_attrs) { - if (tf_alloc_attrs == nullptr) { - return; - } - else { - delete tf_alloc_attrs; - } -} diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index 9a043ce0538..ced57df77d4 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -46,6 +46,17 @@ limitations under the License. extern "C" { #endif +// Allocator Attributes used for tensor allocation. +typedef struct TF_AllocatorAttributes { + size_t struct_size; + // Set boolean to 1 for CPU allocation, else 0. + unsigned char on_host; +} TF_AllocatorAttributes; + + +#define TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE \ + TF_OFFSET_OF_END(TF_AllocatorAttributes, on_host) + // -------------------------------------------------------------------------- // TF_Tensor holds a multi-dimensional array of elements of a single data type. // For all types other than TF_STRING, the data buffer stores elements @@ -152,17 +163,6 @@ TF_CAPI_EXPORT extern void TF_TensorBitcastFrom(const TF_Tensor* from, // Returns bool iff this tensor is aligned. TF_CAPI_EXPORT extern bool TF_TensorIsAligned(const TF_Tensor*); -// Allocator Attributes used for tensor allocation. -typedef struct TF_AllocatorAttributes TF_AllocatorAttributes; - -TF_CAPI_EXPORT extern TF_AllocatorAttributes* TF_NewAllocatorAttributes(); - -TF_CAPI_EXPORT extern void TF_AllocatorAttributesSetOnHost( - TF_AllocatorAttributes* tf_alloc_attrs); - -TF_CAPI_EXPORT extern void TF_DeleteAllocatorAttributes( - TF_AllocatorAttributes* tf_alloc_attrs); - #ifdef __cplusplus } /* end extern "C" */ #endif diff --git a/tensorflow/c/tf_tensor_internal.h b/tensorflow/c/tf_tensor_internal.h index 71cac0afeb1..7a896dc5d11 100644 --- a/tensorflow/c/tf_tensor_internal.h +++ b/tensorflow/c/tf_tensor_internal.h @@ -23,7 +23,6 @@ limitations under the License. #include "tensorflow/core/framework/allocation_description.pb.h" #include "tensorflow/core/framework/tensor.h" #include "tensorflow/core/framework/tensor_shape.h" -#include "tensorflow/core/framework/allocator.h" #include "tensorflow/core/platform/casts.h" // Internal structures used by the C API. These are likely to change and should @@ -125,8 +124,4 @@ Status TF_TensorToTensor(const TF_Tensor* src, Tensor* dst); TF_Tensor* TF_TensorFromTensor(const Tensor& src, Status* status); } // namespace tensorflow -typedef struct TF_AllocatorAttributes { - tensorflow::AllocatorAttributes alloc_attrs; -} TF_AllocatorAttributes; - #endif // TENSORFLOW_C_TF_TENSOR_INTERNAL_H_ From 1182974cc13abf818e80c7a26c5184854870850a Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Wed, 5 Aug 2020 19:18:43 +0000 Subject: [PATCH 25/27] clean up --- tensorflow/c/BUILD | 3 +++ tensorflow/c/kernels.h | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tensorflow/c/BUILD b/tensorflow/c/BUILD index 4a0ab232200..c4c0420aaec 100644 --- a/tensorflow/c/BUILD +++ b/tensorflow/c/BUILD @@ -23,6 +23,7 @@ filegroup( srcs = [ "c_api.h", "c_api_experimental.h", + "c_api_macros.h", "tensor_interface.h", "tf_attrtype.h", "tf_datatype.h", @@ -61,6 +62,7 @@ filegroup( name = "pywrap_required_hdrs", srcs = [ "c_api_internal.h", + "c_api_macros.h", "conversion_macros.h", "python_api.h", "tensor_interface.h", @@ -326,6 +328,7 @@ tf_cuda_library( ], visibility = ["//tensorflow:internal"], deps = [ + ":c_api_macros", ":tensor_interface", ":tf_datatype", ":tf_status", diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index d6a7070de06..ee865613b6e 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -209,7 +209,6 @@ TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, int64_t* dims, int num_dims, TF_AllocatorAttributes* alloc_attrs, TF_Status* status); - #ifdef __cplusplus } /* end extern "C" */ #endif From 078052d2a955fcfe662f97c6b1b225397ced06a9 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Mon, 10 Aug 2020 17:09:52 +0000 Subject: [PATCH 26/27] clean up --- tensorflow/c/kernels_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index 708c39690a8..e216b85c13f 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -587,4 +587,4 @@ void set_tensor_data(TF_Tensor* tensor, T* values, size_t tensor_size_bytes, memcpy(data, values, tensor_size_bytes); #endif } -} // namespace tensorflow \ No newline at end of file +} // namespace tensorflow From a7e4df924652a151677b3e0b95609db27cb04631 Mon Sep 17 00:00:00 2001 From: Daniel Nguyen Date: Tue, 11 Aug 2020 21:01:09 +0000 Subject: [PATCH 27/27] switched from unsigned char to TF_Bool. Added input checking for TF_AllocatorAttributes --- tensorflow/c/BUILD | 1 + tensorflow/c/c_api_macros.h | 6 ++++++ tensorflow/c/kernels.cc | 14 ++++++++++---- tensorflow/c/kernels.h | 2 +- tensorflow/c/kernels_test.cc | 7 +++---- tensorflow/c/tf_tensor.h | 2 +- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/tensorflow/c/BUILD b/tensorflow/c/BUILD index c4c0420aaec..7b78fdb4cf6 100644 --- a/tensorflow/c/BUILD +++ b/tensorflow/c/BUILD @@ -81,6 +81,7 @@ tf_cuda_library( hdrs = [ "c_api.h", "c_api_internal.h", + "c_api_macros.h", "tf_datatype.h", "tf_tensor.h", "tf_tstring.h", diff --git a/tensorflow/c/c_api_macros.h b/tensorflow/c/c_api_macros.h index ce24e4d8cbd..58547a57b6e 100644 --- a/tensorflow/c/c_api_macros.h +++ b/tensorflow/c/c_api_macros.h @@ -30,6 +30,12 @@ limitations under the License. #endif // _WIN32 #endif // SWIG +// TF_Bool is the C API typedef for unsigned char, while TF_BOOL is +// the datatype for boolean tensors. +#ifndef TF_BOOL_DEFINED +#define TF_Bool unsigned char +#endif // TF_BOOL_DEFINED + // Macro used to calculate struct size for maintaining ABI stability across // different struct implementations. #ifndef TF_OFFSET_OF_END diff --git a/tensorflow/c/kernels.cc b/tensorflow/c/kernels.cc index 6d9d7d57517..cce6f2c494d 100644 --- a/tensorflow/c/kernels.cc +++ b/tensorflow/c/kernels.cc @@ -261,7 +261,6 @@ TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, int index, size_t len, TF_Status* status) { TF_SetStatus(status, TF_OK, ""); auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); - static_assert(sizeof(int64_t) == sizeof(tensorflow::int64), "64-bit int types should match in size"); tensorflow::gtl::ArraySlice dimarray( @@ -286,22 +285,29 @@ TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, TF_AllocatorAttributes* attributes, TF_Status* status) { auto* cc_ctx = reinterpret_cast<::tensorflow::OpKernelContext*>(context); - TF_SetStatus(status, TF_OK, ""); + TF_SetStatus(status, TF_OK, ""); + static_assert(sizeof(int64_t) == sizeof(tensorflow::int64), + "64-bit int types should match in size"); tensorflow::gtl::ArraySlice dimarray( reinterpret_cast(dims), num_dims); + if (attributes && !attributes->struct_size) { + TF_SetStatus(status, TF_INVALID_ARGUMENT, "TF_AllocatorAttributes struct " + "size member must be set to TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE"); + return nullptr; + } tensorflow::AllocatorAttributes allocator_attr; - if (attributes->on_host) { + if (attributes && attributes->on_host) { allocator_attr.set_on_host(true); } tensorflow::Status s; tensorflow::Tensor tensor; - TF_Tensor* tf_tensor; s = cc_ctx->allocate_temp(static_cast(dtype), tensorflow::TensorShape(dimarray), &tensor, allocator_attr); if (!s.ok()) { ::tensorflow::Set_TF_Status_from_Status(status, s); return nullptr; } + TF_Tensor* tf_tensor; tf_tensor = TF_TensorFromTensor(tensor, &s); if (!s.ok()) { ::tensorflow::Set_TF_Status_from_Status(status, s); diff --git a/tensorflow/c/kernels.h b/tensorflow/c/kernels.h index ee865613b6e..0be31b76839 100644 --- a/tensorflow/c/kernels.h +++ b/tensorflow/c/kernels.h @@ -203,7 +203,7 @@ TF_CAPI_EXPORT TF_Tensor* TF_AllocateOutput(TF_OpKernelContext* context, // Allocates a temporary Tensor of the specified type and shape. The // Tensor must not be used after kernel construction is // complete. - +// // num_dims must equal the size of array dims TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTemp(TF_OpKernelContext* context, TF_DataType dtype, int64_t* dims, int num_dims, TF_AllocatorAttributes* diff --git a/tensorflow/c/kernels_test.cc b/tensorflow/c/kernels_test.cc index e216b85c13f..7663a3570eb 100644 --- a/tensorflow/c/kernels_test.cc +++ b/tensorflow/c/kernels_test.cc @@ -368,13 +368,12 @@ class DeviceKernelOpTest : public OpsTestBase { #endif }; -// Helper function for tests that validates that the tensor has -// shape and type corresponding to dims and dtype. +// Validates that the tensor has shape and type corresponding to +// dims and dtype. void validate_tensor(TF_Tensor* tensor, int64_t* dims, int64_t num_dims, TF_DataType dtype); -// Helper function for tests that copies data of length -// tensor_size_bytes from values to tensor +// Copies data of length tensor_size_bytes from values to tensor. template void set_tensor_data(TF_Tensor* tensor, T* values, size_t tensor_size_bytes, TF_OpKernelContext* ctx); diff --git a/tensorflow/c/tf_tensor.h b/tensorflow/c/tf_tensor.h index ced57df77d4..1faa368f25a 100644 --- a/tensorflow/c/tf_tensor.h +++ b/tensorflow/c/tf_tensor.h @@ -50,7 +50,7 @@ extern "C" { typedef struct TF_AllocatorAttributes { size_t struct_size; // Set boolean to 1 for CPU allocation, else 0. - unsigned char on_host; + TF_Bool on_host; } TF_AllocatorAttributes;