1c8b59c046895fa5b6d79f73e0b5817330fcfbfc1A. Unique TensorFlower/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
29c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur
39c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurLicensed under the Apache License, Version 2.0 (the "License");
49c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudluryou may not use this file except in compliance with the License.
59c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurYou may obtain a copy of the License at
69c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur
79c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur    http://www.apache.org/licenses/LICENSE-2.0
89c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur
99c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurUnless required by applicable law or agreed to in writing, software
109c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlurdistributed under the License is distributed on an "AS IS" BASIS,
119c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurSee the License for the specific language governing permissions and
139c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlurlimitations under the License.
149c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur==============================================================================*/
159c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur
16f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/core/framework/tensor_slice.h"
17b481783fe0e00a86f6feb20a8dcad5fc4fc936a4Josh Levenberg#include <vector>
18f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/core/lib/core/errors.h"
19f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jain#include "tensorflow/core/lib/strings/numbers.h"
20f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/core/lib/strings/str_util.h"
2156313def004795f75ef8281a0294c958d28f1e06Vijay Vasudevan#include "tensorflow/core/lib/strings/strcat.h"
2256313def004795f75ef8281a0294c958d28f1e06Vijay Vasudevan#include "tensorflow/core/platform/logging.h"
23f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
24f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace tensorflow {
25f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
26f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurTensorSlice::TensorSlice(int dim) { SetFullSlice(dim); }
27f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
28f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurTensorSlice::TensorSlice(const TensorSliceProto& proto) {
29f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.reserve(proto.extent_size());
30f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.reserve(proto.extent_size());
31f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (const auto& e : proto.extent()) {
32f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    starts_.push_back(e.start());
33f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    lengths_.push_back(GetExtentLength(e));
34f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
35f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
36f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
37f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan JainTensorSlice::TensorSlice(
38f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jain    std::initializer_list<std::pair<int64, int64>> extents) {
39f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.reserve(extents.size());
40f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.reserve(extents.size());
41f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (const auto& e : extents) {
42f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    starts_.push_back(e.first);
43f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    lengths_.push_back(e.second);
44f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
45f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
46f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
47f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurStatus TensorSlice::Parse(const string& str, TensorSlice* slice) {
48f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  std::vector<string> items = str_util::Split(str, ':', str_util::SkipEmpty());
49f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  slice->starts_.reserve(items.size());
50f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  slice->lengths_.reserve(items.size());
51f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (const string& x : items) {
52f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jain    int64 s, l;
53f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (x == "-") {
54f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // "everything"
55f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      s = 0;
56f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      l = kFullExtent;
57f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
58f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jain      std::vector<string> sl = str_util::Split(x, ',', str_util::SkipEmpty());
59f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jain      if (sl.size() != 2 || !strings::safe_strto64(sl[0], &s) ||
60f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jain          !strings::safe_strto64(sl[1], &l)) {
61f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        return errors::InvalidArgument(
62f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            "Expected a pair of numbers or '-' "
63f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            "but got '",
64f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            x, "': string = ", str);
65f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
66f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (s < 0 || l <= 0) {
67f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        return errors::InvalidArgument(
68f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            "Expected non-negative start and "
69f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            "positive length but got start = ",
70f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            s, ", length = ", l, ": string = ", str);
71f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
72f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
73f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    slice->starts_.push_back(s);
74f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    slice->lengths_.push_back(l);
75f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
76f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
77f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return Status::OK();
78f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
79f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
80f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::Clear() {
81f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.clear();
82f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.clear();
83f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
84f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
85d7cc0cf1d0e616e1454872d3b45c365dc4537fb2Zongheng Yangbool TensorSlice::IsFull() const {
86d7cc0cf1d0e616e1454872d3b45c365dc4537fb2Zongheng Yang  for (int d = 0; d < dims(); ++d) {
87d7cc0cf1d0e616e1454872d3b45c365dc4537fb2Zongheng Yang    if (!IsFullAt(d)) return false;
88d7cc0cf1d0e616e1454872d3b45c365dc4537fb2Zongheng Yang  }
89d7cc0cf1d0e616e1454872d3b45c365dc4537fb2Zongheng Yang  return true;
90d7cc0cf1d0e616e1454872d3b45c365dc4537fb2Zongheng Yang}
91d7cc0cf1d0e616e1454872d3b45c365dc4537fb2Zongheng Yang
92f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::SetFullSlice(int dim) {
93f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  Clear();
94f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.reserve(dim);
95f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.reserve(dim);
96f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dim; ++d) {
97f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    starts_.push_back(0);
98f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    lengths_.push_back(kFullExtent);
99f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
100f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
101f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
102f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::Extend(int dim) {
103f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  int old_dim = dims();
104f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  DCHECK_LE(old_dim, dim);
105f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.resize(dim);
106f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.resize(dim);
107f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = old_dim; d < dim; ++d) {
108f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    starts_[d] = 0;
109f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    lengths_[d] = kFullExtent;
110f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
111f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
112f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
113f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::AsProto(TensorSliceProto* proto) const {
114f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
115f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    TensorSliceProto::Extent* e = proto->add_extent();
116f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    // We only need to record the explicit slice for non-full slices
117f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (!IsFullAt(d)) {
118f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      e->set_start(starts_[d]);
119f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      e->set_length(lengths_[d]);
120f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
121f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
122f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
123f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
124f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurstring TensorSlice::DebugString() const {
125f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  string buffer;
126f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  bool first = true;
127f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
128f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (!first) {
129f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      buffer.append(":");
130f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
131f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    string s;
132f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (IsFullAt(d)) {
133f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      buffer.append("-");
134f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
135f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      strings::StrAppend(&buffer, starts_[d], ",", lengths_[d]);
136f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
137f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    first = false;
138f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
139f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return buffer;
140f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
141f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
142f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurbool TensorSlice::Intersect(const TensorSlice& other,
143f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                            TensorSlice* result) const {
144f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // First, if two slices have different ranks, they obviously don't overlap
145f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // -- in fact they are not compatible.
146f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (dims() != other.dims()) {
147f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    return false;
148f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
149f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
150f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Setting the result to the right dimension
151f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (result) {
152f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    result->SetFullSlice(dims());
153f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
154f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // The two slices overlap if they overlap in all dimensions.
155f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
156f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (IsFullAt(d)) {
157f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (result) {
158f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result->set_start(d, other.start(d));
159f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result->set_length(d, other.length(d));
160f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
161f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else if (other.IsFullAt(d)) {
162f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (result) {
163f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result->set_start(d, start(d));
164f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result->set_length(d, length(d));
165f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
166f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
167f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // If we have an intersection here, it should have a start that is the
168f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // max of the two starts and an end that is the min of the two ends.
169f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jain      int64 s = std::max(start(d), other.start(d));
170f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jain      int64 l = std::min(end(d), other.end(d)) - s;
171f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (l > 0) {
172f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // We have a real intersection
173f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        if (result) {
174f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur          result->set_start(d, s);
175f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur          result->set_length(d, l);
176f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        }
177f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      } else {
178f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // We don't have an intersection for this dimension -- thus we don't
179f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // have any intersection at all.
180f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        if (result) {
181f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur          result->Clear();
182f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        }
183f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        return false;
184f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
185f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
186f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
187f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // If we are here, we know there is overlap in every dimension.
188f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return true;
189f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
190f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
1919ed3b81c8898cd86a8611c589353dbfb0e8f51d7Zongheng Yangbool TensorSlice::operator==(const TensorSlice& other) const {
1929ed3b81c8898cd86a8611c589353dbfb0e8f51d7Zongheng Yang  return dims() == other.dims() && starts_ == other.starts_ &&
1939ed3b81c8898cd86a8611c589353dbfb0e8f51d7Zongheng Yang         lengths_ == other.lengths_;
1949ed3b81c8898cd86a8611c589353dbfb0e8f51d7Zongheng Yang}
1959ed3b81c8898cd86a8611c589353dbfb0e8f51d7Zongheng Yang
196f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::ComputeRelative(const TensorSlice& sub,
197f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                                  TensorSlice* relative) const {
198f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  DCHECK_EQ(dims(), sub.dims());
199f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  relative->SetFullSlice(dims());
200f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
201f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (IsFullAt(d)) {
202f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      relative->set_start(d, sub.start(d));
203f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      relative->set_length(d, sub.length(d));
204f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
205f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // Otherwise the relative start is the difference between the start of
206f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // sub and the start of base
207f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      relative->set_start(d, sub.start(d) - start(d));
208f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      relative->set_length(d, sub.length(d));
209f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
210f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
211f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
212f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
213174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlowervoid TensorSlice::UpdateToCover(const TensorSlice& other) {
214174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower  DCHECK_EQ(dims(), other.dims());
215174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower  for (int d = 0; d < dims(); ++d) {
216174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower    if (!IsFullAt(d)) {
217174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower      if (other.IsFullAt(d)) {
218174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower        starts_[d] = 0;
219174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower        lengths_[d] = kFullExtent;
220174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower      } else {
2214392eee66fe9e452e5b9ce8188347a58476f56f3A. Unique TensorFlower        const auto new_end = std::max(end(d), other.end(d));
2224392eee66fe9e452e5b9ce8188347a58476f56f3A. Unique TensorFlower        set_start(d, std::min(start(d), other.start(d)));
223174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower        set_length(d, new_end - start(d));
224174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower      }
225174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower    }
226174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower  }
227174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower}
228174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower
229f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// static
230f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurbool TensorSlice::HasExtentLength(const TensorSliceProto::Extent& extent) {
231f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return extent.has_length_case() == TensorSliceProto::Extent::kLength;
232f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
233f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
234f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// static
235f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurint64 TensorSlice::GetExtentLength(const TensorSliceProto::Extent& extent) {
236f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (!HasExtentLength(extent)) return -1;
237f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return extent.length();
238f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
239f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
240f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurStatus TensorSlice::SliceTensorShape(const TensorShape& shape,
24156313def004795f75ef8281a0294c958d28f1e06Vijay Vasudevan                                     TensorShape* result_shape) const {
242f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  result_shape->Clear();
243f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Mismatching ranks: we can't apply the slice at all.
244f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (shape.dims() != dims()) {
245f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    return errors::Internal("Mismatching ranks: shape = ", shape.DebugString(),
246f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                            ", slice = ", DebugString());
247f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
248f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
249f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (IsFullAt(d)) {
250f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      result_shape->AddDim(shape.dim_size(d));
251f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
252f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // Check if the extent applies to the dimension
253f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (end(d) <= shape.dim_size(d)) {
254f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // Yes: the end is within the range of the dim -- we adjust the result
255f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // shape so that its size along this dimension is the length of the
256f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // slice.
257f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result_shape->AddDim(length(d));
258f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      } else {
259f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // The extent doesn't apply to the dimension
260f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result_shape->Clear();
261f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        return errors::Internal("Extent in dimension ", d,
262f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                                " out of bounds: shape = ", shape.DebugString(),
263f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                                ", slice = ", DebugString());
264f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
265f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
266f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
267f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // If we are here, we have successfully applied the shape.
268f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return Status::OK();
269f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
270f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
271f5eaf77f0442ba1064b7d68ddfe551a27d720ac6Rohan Jainconst int64 TensorSlice::kFullExtent = -1;
272f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
273f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}  // namespace tensorflow
274