| 546 | |
| 547 | template <typename Device, typename T> |
| 548 | Status TensorArray::LockedRead(OpKernelContext* ctx, const int32 index, |
| 549 | PersistentTensor* value) { |
| 550 | TF_RETURN_IF_ERROR(LockedReturnIfClosed()); |
| 551 | if ((index < 0) || |
| 552 | (!is_grad_ && (static_cast<size_t>(index) >= tensors_.size()))) { |
| 553 | return errors::InvalidArgument("Tried to read from index ", index, |
| 554 | " but array size is: ", tensors_.size()); |
| 555 | } |
| 556 | size_t index_t = static_cast<size_t>(index); |
| 557 | if ((is_grad_ && (index_t >= tensors_.size() || !tensors_[index].written)) || |
| 558 | (!is_grad_ && (index_t < tensors_.size() && !tensors_[index].written))) { |
| 559 | // Special case returning zeros if this is a gradient read that happens |
| 560 | // after a stop_gradients call with dynamic forward TensorArrays. |
| 561 | // There is sometimes a race condition where the gradient is not |
| 562 | // written due to stop_gradients, but is later read. |
| 563 | TensorShape element_shape; |
| 564 | if (is_grad_ && index_t < tensors_.size() && |
| 565 | tensors_[index].shape.dims() > 0) { |
| 566 | // A gradient TensorArray has more specific gradient information |
| 567 | // available for each entry. A forward TensorArray must rely on |
| 568 | // the global element_shape_ to fill in zeros on read. |
| 569 | element_shape = tensors_[index].shape; |
| 570 | } else if (!element_shape_.IsFullyDefined()) { |
| 571 | return errors::InvalidArgument( |
| 572 | "TensorArray ", handle_.vec<tstring>()(1), |
| 573 | ": Could not read from TensorArray index ", index, |
| 574 | ". Furthermore, the element shape is not fully defined: ", |
| 575 | element_shape_.DebugString(), |
| 576 | ". It is possible you are working with a resizeable TensorArray and " |
| 577 | "stop_gradients is not allowing the gradients to be written. If you " |
| 578 | "set the full " |
| 579 | "element_shape property on the forward TensorArray, the proper " |
| 580 | "all-zeros tensor " |
| 581 | "will be returned instead of incurring this error."); |
| 582 | } else { |
| 583 | element_shape_.AsTensorShape(&element_shape); // Always succeeds. |
| 584 | } |
| 585 | if (index_t >= tensors_.size()) { |
| 586 | // Fill in tensors_ up to index to have known shape. |
| 587 | size_t old_tensors_size = tensors_.size(); |
| 588 | tensors_.resize(index + 1); |
| 589 | for (size_t i = old_tensors_size; i < index + 1; ++i) { |
| 590 | tensors_[i].shape = element_shape; |
| 591 | tensors_[i].written = true; |
| 592 | } |
| 593 | } else { |
| 594 | tensors_[index].shape = element_shape; |
| 595 | tensors_[index].written = true; |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | TensorAndState& t = tensors_[index]; |
| 600 | |
| 601 | if (t.cleared) { |
| 602 | return errors::InvalidArgument("TensorArray ", handle_.vec<tstring>()(1), |
| 603 | ": Could not read index ", index, |
| 604 | " twice because it was cleared after a " |
| 605 | "previous read (perhaps try setting " |
nothing calls this directly
no test coverage detected