Non-static for testing.
| 279 | |
| 280 | // Non-static for testing. |
| 281 | TF_Tensor* TF_TensorFromTensor(const tensorflow::Tensor& src, |
| 282 | TF_Status* status) { |
| 283 | TF_SetStatus(status, TF_OK, ""); |
| 284 | if (!src.IsInitialized()) { |
| 285 | Set_TF_Status_from_Status( |
| 286 | status, FailedPrecondition( |
| 287 | "attempt to use a tensor with an uninitialized value")); |
| 288 | return nullptr; |
| 289 | } |
| 290 | if (src.NumElements() == 0) { |
| 291 | return EmptyTensor(static_cast<TF_DataType>(src.dtype()), src.shape()); |
| 292 | } |
| 293 | if (src.dtype() == tensorflow::DT_RESOURCE) { |
| 294 | if (src.shape().dims() != 0) { |
| 295 | Set_TF_Status_from_Status( |
| 296 | status, InvalidArgument( |
| 297 | "Unexpected non-scalar DT_RESOURCE tensor seen (shape: ", |
| 298 | src.shape().DebugString(), |
| 299 | "). Please file a bug at " |
| 300 | "https://github.com/tensorflow/tensorflow/issues/new, " |
| 301 | "ideally with a " |
| 302 | "short code snippet that reproduces this error.")); |
| 303 | return nullptr; |
| 304 | } |
| 305 | const string str = |
| 306 | src.scalar<tensorflow::ResourceHandle>()().SerializeAsString(); |
| 307 | TF_Tensor* t = TF_AllocateTensor(TF_RESOURCE, {}, 0, str.size()); |
| 308 | std::memcpy(TF_TensorData(t), str.c_str(), str.size()); |
| 309 | return t; |
| 310 | } |
| 311 | if (src.dtype() != tensorflow::DT_STRING) { |
| 312 | auto* result = new TF_Tensor(); |
| 313 | if (!result->tensor.CopyFrom(src, src.shape())) { |
| 314 | delete result; |
| 315 | return nullptr; |
| 316 | } |
| 317 | return result; |
| 318 | } |
| 319 | // DT_STRING tensors require a copying since TF_Tensor.buffer expects a flatly |
| 320 | // encoded sequence of strings. |
| 321 | |
| 322 | // Compute bytes needed for encoding. |
| 323 | size_t size = 0; |
| 324 | const auto& srcarray = src.flat<tstring>(); |
| 325 | for (int i = 0; i < srcarray.size(); ++i) { |
| 326 | const string& s = srcarray(i); |
| 327 | // uint64 starting_offset, TF_StringEncode-d string. |
| 328 | size += sizeof(tensorflow::uint64) + TF_StringEncodedSize(s.size()); |
| 329 | } |
| 330 | |
| 331 | // Encode all strings. |
| 332 | char* base = new char[size]; |
| 333 | char* data_start = base + sizeof(tensorflow::uint64) * srcarray.size(); |
| 334 | char* dst = data_start; // Where next string is encoded. |
| 335 | size_t dst_len = size - static_cast<size_t>(data_start - base); |
| 336 | tensorflow::uint64* offsets = reinterpret_cast<tensorflow::uint64*>(base); |
| 337 | for (int i = 0; i < srcarray.size(); ++i) { |
| 338 | *offsets = (dst - data_start); |