| 31 | } |
| 32 | |
| 33 | void UniqueTensorReferences::Add(const Tensor& tensor) { |
| 34 | DCHECK(!frozen_); |
| 35 | // Do nothing if the tensor has a null buffer. |
| 36 | if (tensor.IsInitialized() && tensor.NumElements() > 0) { |
| 37 | if (referenced_tensors_set_ != nullptr) { |
| 38 | // There are enough tensors that we are using a hash set to |
| 39 | // de-duplicate. |
| 40 | const TensorReference tensor_ref(tensor); |
| 41 | if (!referenced_tensors_set_->insert(tensor_ref).second) { |
| 42 | // The tensor was a duplicate, so discard the reference. |
| 43 | tensor_ref.Unref(); |
| 44 | } |
| 45 | } else { |
| 46 | for (size_t i = 0; i < referenced_tensors_vector_.size(); ++i) { |
| 47 | if (referenced_tensors_vector_[i].SharesBufferWith(tensor)) { |
| 48 | // tensor is a duplicate, so nothing to do. |
| 49 | return; |
| 50 | } |
| 51 | } |
| 52 | referenced_tensors_vector_.push_back(TensorReference(tensor)); |
| 53 | if (kInVector == referenced_tensors_vector_.size()) { |
| 54 | // There are too many tensors to keep using the N^2 algorithm |
| 55 | // so start de-duplicating using a set. |
| 56 | // Transfer the refs from the vector to the set. |
| 57 | DCHECK(referenced_tensors_set_ == nullptr); |
| 58 | referenced_tensors_set_ = new ReferencedTensorsSet; |
| 59 | referenced_tensors_set_->reserve(kInVector); |
| 60 | referenced_tensors_set_->insert(referenced_tensors_vector_.begin(), |
| 61 | referenced_tensors_vector_.end()); |
| 62 | DCHECK_EQ(kInVector, referenced_tensors_set_->size()); |
| 63 | referenced_tensors_vector_.clear(); |
| 64 | } |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | void UniqueTensorReferences::FreezeAndReturnReferences( |
| 70 | TensorReferenceVector* out_vector) { |
nothing calls this directly
no test coverage detected