tensor_slice.cc revision c8b59c046895fa5b6d79f73e0b5817330fcfbfc1
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"
19f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/core/lib/strings/str_util.h"
2056313def004795f75ef8281a0294c958d28f1e06Vijay Vasudevan#include "tensorflow/core/lib/strings/strcat.h"
2156313def004795f75ef8281a0294c958d28f1e06Vijay Vasudevan#include "tensorflow/core/platform/logging.h"
22f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
23f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace tensorflow {
24f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
25f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurTensorSlice::TensorSlice(int dim) { SetFullSlice(dim); }
26f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
27f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurTensorSlice::TensorSlice(const TensorSliceProto& proto) {
28f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.reserve(proto.extent_size());
29f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.reserve(proto.extent_size());
30f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (const auto& e : proto.extent()) {
31f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    starts_.push_back(e.start());
32f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    lengths_.push_back(GetExtentLength(e));
33f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
34f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
35f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
36f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurTensorSlice::TensorSlice(std::initializer_list<std::pair<int, int>> extents) {
37f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.reserve(extents.size());
38f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.reserve(extents.size());
39f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (const auto& e : extents) {
40f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    starts_.push_back(e.first);
41f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    lengths_.push_back(e.second);
42f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
43f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
44f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
45f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurStatus TensorSlice::Parse(const string& str, TensorSlice* slice) {
46f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  std::vector<string> items = str_util::Split(str, ':', str_util::SkipEmpty());
47f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  slice->starts_.reserve(items.size());
48f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  slice->lengths_.reserve(items.size());
49f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (const string& x : items) {
50f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    int s, l;
51f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (x == "-") {
52f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // "everything"
53f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      s = 0;
54f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      l = kFullExtent;
55f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
56f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      char junk;
57f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (sscanf(x.c_str(), "%d,%d%c", &s, &l, &junk) != 2) {
58f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        return errors::InvalidArgument(
59f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            "Expected a pair of numbers or '-' "
60f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            "but got '",
61f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            x, "': string = ", str);
62f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
63f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (s < 0 || l <= 0) {
64f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        return errors::InvalidArgument(
65f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            "Expected non-negative start and "
66f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            "positive length but got start = ",
67f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur            s, ", length = ", l, ": string = ", str);
68f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
69f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
70f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    slice->starts_.push_back(s);
71f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    slice->lengths_.push_back(l);
72f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
73f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
74f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return Status::OK();
75f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
76f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
77f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::Clear() {
78f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.clear();
79f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.clear();
80f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
81f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
82f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::SetFullSlice(int dim) {
83f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  Clear();
84f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.reserve(dim);
85f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.reserve(dim);
86f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dim; ++d) {
87f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    starts_.push_back(0);
88f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    lengths_.push_back(kFullExtent);
89f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
90f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
91f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
92f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::Extend(int dim) {
93f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  int old_dim = dims();
94f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  DCHECK_LE(old_dim, dim);
95f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  starts_.resize(dim);
96f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  lengths_.resize(dim);
97f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = old_dim; d < dim; ++d) {
98f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    starts_[d] = 0;
99f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    lengths_[d] = kFullExtent;
100f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
101f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
102f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
103f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::AsProto(TensorSliceProto* proto) const {
104f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
105f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    TensorSliceProto::Extent* e = proto->add_extent();
106f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    // We only need to record the explicit slice for non-full slices
107f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (!IsFullAt(d)) {
108f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      e->set_start(starts_[d]);
109f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      e->set_length(lengths_[d]);
110f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
111f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
112f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
113f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
114f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurstring TensorSlice::DebugString() const {
115f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  string buffer;
116f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  bool first = true;
117f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
118f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (!first) {
119f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      buffer.append(":");
120f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
121f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    string s;
122f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (IsFullAt(d)) {
123f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      buffer.append("-");
124f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
125f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      strings::StrAppend(&buffer, starts_[d], ",", lengths_[d]);
126f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
127f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    first = false;
128f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
129f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return buffer;
130f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
131f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
132f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurbool TensorSlice::Intersect(const TensorSlice& other,
133f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                            TensorSlice* result) const {
134f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // First, if two slices have different ranks, they obviously don't overlap
135f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // -- in fact they are not compatible.
136f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (dims() != other.dims()) {
137f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    return false;
138f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
139f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
140f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Setting the result to the right dimension
141f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (result) {
142f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    result->SetFullSlice(dims());
143f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
144f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // The two slices overlap if they overlap in all dimensions.
145f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
146f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (IsFullAt(d)) {
147f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (result) {
148f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result->set_start(d, other.start(d));
149f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result->set_length(d, other.length(d));
150f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
151f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else if (other.IsFullAt(d)) {
152f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (result) {
153f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result->set_start(d, start(d));
154f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result->set_length(d, length(d));
155f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
156f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
157f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // If we have an intersection here, it should have a start that is the
158f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // max of the two starts and an end that is the min of the two ends.
159f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      int s = std::max(start(d), other.start(d));
160f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      int l = std::min(end(d), other.end(d)) - s;
161f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (l > 0) {
162f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // We have a real intersection
163f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        if (result) {
164f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur          result->set_start(d, s);
165f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur          result->set_length(d, l);
166f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        }
167f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      } else {
168f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // We don't have an intersection for this dimension -- thus we don't
169f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // have any intersection at all.
170f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        if (result) {
171f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur          result->Clear();
172f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        }
173f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        return false;
174f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
175f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
176f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
177f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // If we are here, we know there is overlap in every dimension.
178f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return true;
179f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
180f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
181f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurvoid TensorSlice::ComputeRelative(const TensorSlice& sub,
182f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                                  TensorSlice* relative) const {
183f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  DCHECK_EQ(dims(), sub.dims());
184f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  relative->SetFullSlice(dims());
185f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
186f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (IsFullAt(d)) {
187f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      relative->set_start(d, sub.start(d));
188f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      relative->set_length(d, sub.length(d));
189f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
190f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // Otherwise the relative start is the difference between the start of
191f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // sub and the start of base
192f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      relative->set_start(d, sub.start(d) - start(d));
193f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      relative->set_length(d, sub.length(d));
194f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
195f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
196f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
197f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
198174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlowervoid TensorSlice::UpdateToCover(const TensorSlice& other) {
199174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower  DCHECK_EQ(dims(), other.dims());
200174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower  for (int d = 0; d < dims(); ++d) {
201174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower    if (!IsFullAt(d)) {
202174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower      if (other.IsFullAt(d)) {
203174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower        starts_[d] = 0;
204174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower        lengths_[d] = kFullExtent;
205174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower      } else {
2064392eee66fe9e452e5b9ce8188347a58476f56f3A. Unique TensorFlower        const auto new_end = std::max(end(d), other.end(d));
2074392eee66fe9e452e5b9ce8188347a58476f56f3A. Unique TensorFlower        set_start(d, std::min(start(d), other.start(d)));
208174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower        set_length(d, new_end - start(d));
209174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower      }
210174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower    }
211174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower  }
212174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower}
213174fd60ebe78b22288c6e9b6c079c3ebb58f56d0A. Unique TensorFlower
214f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// static
215f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurbool TensorSlice::HasExtentLength(const TensorSliceProto::Extent& extent) {
216f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return extent.has_length_case() == TensorSliceProto::Extent::kLength;
217f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
218f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
219f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// static
220f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurint64 TensorSlice::GetExtentLength(const TensorSliceProto::Extent& extent) {
221f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (!HasExtentLength(extent)) return -1;
222f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return extent.length();
223f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
224f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
225f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath KudlurStatus TensorSlice::SliceTensorShape(const TensorShape& shape,
22656313def004795f75ef8281a0294c958d28f1e06Vijay Vasudevan                                     TensorShape* result_shape) const {
227f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  result_shape->Clear();
228f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // Mismatching ranks: we can't apply the slice at all.
229f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  if (shape.dims() != dims()) {
230f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    return errors::Internal("Mismatching ranks: shape = ", shape.DebugString(),
231f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                            ", slice = ", DebugString());
232f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
233f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  for (int d = 0; d < dims(); ++d) {
234f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    if (IsFullAt(d)) {
235f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      result_shape->AddDim(shape.dim_size(d));
236f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    } else {
237f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      // Check if the extent applies to the dimension
238f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      if (end(d) <= shape.dim_size(d)) {
239f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // Yes: the end is within the range of the dim -- we adjust the result
240f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // shape so that its size along this dimension is the length of the
241f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // slice.
242f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result_shape->AddDim(length(d));
243f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      } else {
244f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        // The extent doesn't apply to the dimension
245f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        result_shape->Clear();
246f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur        return errors::Internal("Extent in dimension ", d,
247f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                                " out of bounds: shape = ", shape.DebugString(),
248f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur                                ", slice = ", DebugString());
249f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur      }
250f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur    }
251f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  }
252f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  // If we are here, we have successfully applied the shape.
253f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur  return Status::OK();
254f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}
255f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
256f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurconst int TensorSlice::kFullExtent = -1;
257f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur
258f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur}  // namespace tensorflow
259