tensor_shape.h revision e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6
1c8b59c046895fa5b6d79f73e0b5817330fcfbfc1A. Unique TensorFlower/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 3db7478e8998f7703c57a75a950c905ec0cb59d7bJosh LevenbergLicensed under the Apache License, Version 2.0 (the "License"); 4db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergyou may not use this file except in compliance with the License. 5db7478e8998f7703c57a75a950c905ec0cb59d7bJosh LevenbergYou may obtain a copy of the License at 6db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 7db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg http://www.apache.org/licenses/LICENSE-2.0 8db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 9db7478e8998f7703c57a75a950c905ec0cb59d7bJosh LevenbergUnless required by applicable law or agreed to in writing, software 10db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergdistributed under the License is distributed on an "AS IS" BASIS, 11db7478e8998f7703c57a75a950c905ec0cb59d7bJosh LevenbergWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12db7478e8998f7703c57a75a950c905ec0cb59d7bJosh LevenbergSee the License for the specific language governing permissions and 13db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberglimitations under the License. 14db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg==============================================================================*/ 15db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 16db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#ifndef TENSORFLOW_CORE_FRAMEWORK_TENSOR_SHAPE_H_ 17db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#define TENSORFLOW_CORE_FRAMEWORK_TENSOR_SHAPE_H_ 18db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 19db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include <string> 20db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 21db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor" 22db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "tensorflow/core/framework/tensor_shape.pb.h" 239934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower#include "tensorflow/core/framework/types.pb.h" 24db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "tensorflow/core/lib/core/errors.h" 25db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "tensorflow/core/lib/core/status.h" 26db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "tensorflow/core/lib/core/stringpiece.h" 27db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "tensorflow/core/lib/gtl/array_slice.h" 28db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "tensorflow/core/lib/gtl/inlined_vector.h" 29db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "tensorflow/core/lib/strings/strcat.h" 30db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#include "tensorflow/core/platform/logging.h" 31db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 32db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergnamespace tensorflow { 33db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 34120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower// START_SKIP_DOXYGEN 35db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergclass TensorShapeIter; // Declared below 36120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower// END_SKIP_DOXYGEN 37120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower 38120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// Represents the shape of a Tensor. 39120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// 40120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// A tensor's shape is denoted by its number of dimensions and a size for each 41120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// dimension. For example, a Tensor represented by a 3 x 4 matrix would have 42120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// a shape of 2-D, [3,4]. 43120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// 44120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// If you know the exact shape of your Tensor when you create the TensorShape 45120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// object, you can specify it then, or you can create a TensorShape with 46120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// zero dimensions and one element, and call AddDim() to add dimensions later. 47db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergclass TensorShape { 48db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg public: 49db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// \brief Construct a `TensorShape` from the provided sizes. 50db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `dim_sizes[i] >= 0` 51db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg explicit TensorShape(gtl::ArraySlice<int64> dim_sizes); 52db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg TensorShape(std::initializer_list<int64> dim_sizes) 53db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg : TensorShape(gtl::ArraySlice<int64>(dim_sizes)) {} 54db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 55db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `IsValid(proto)` 56db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg explicit TensorShape(const TensorShapeProto& proto); 57db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 58db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Create a tensor shape with no dimensions and one element, which you can 59db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// then call `AddDim()` on. 60db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg TensorShape(); 61db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 62df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower ~TensorShape(); 63df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 64df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower /// Copy the specified shape 65df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower TensorShape(const TensorShape& b); 66df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower void operator=(const TensorShape& b); 67df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 68f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower /// Move the specified shape. After moving, <b> is safe for destruction and 69f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // can be reassigned into, but its dimensions and number of elements can be 70f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // nonsensical (e.g., negative dimension sizes, or number of elements not 71f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // properly recomputed). 72f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower TensorShape(TensorShape&& b); 73f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower void operator=(TensorShape&& b); 74f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower 75db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Returns `true` iff `proto` is a valid tensor shape. 76db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg static bool IsValid(const TensorShapeProto& proto); 77db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 78db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Returns `OK` iff `proto` is a valid tensor shape, and a descriptive error 79db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// status otherwise. 80db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg static Status IsValidShape(const TensorShapeProto& proto); 81db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 82db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Clear a tensor shape 83db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg void Clear(); 84db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 85db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// \brief Add a dimension to the end ("inner-most"). 86db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `size >= 0` 87db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg void AddDim(int64 size); 88db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 89db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Appends all the dimensions from `shape`. 90db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg void AppendShape(const TensorShape& shape); 91db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 92ffd88925f4a29e68779f5b95eb99d60b40daf184David G. Andersen // Maximum number of dimensions in a tensor. 93ffd88925f4a29e68779f5b95eb99d60b40daf184David G. Andersen static constexpr int MaxDimensions() { return 255; } 94ffd88925f4a29e68779f5b95eb99d60b40daf184David G. Andersen 95db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// \brief Insert a dimension somewhere in the `TensorShape`. 96db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `0 <= d <= dims()` 97db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `size >= 0` 98db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg void InsertDim(int d, int64 size); 99db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 100db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// \brief Modifies the size of the dimension `d` to be `size` 101db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `0 <= d < dims()` 102db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `size >= 0` 103db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg void set_dim(int d, int64 size); 104db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 105db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// \brief Removes dimension `d` from the `TensorShape`. 106db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `0 <= d < dims()` 107db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg void RemoveDim(int d); 108db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 109db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Return the number of dimensions in the tensor. 110df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower int dims() const { 1119ccc4b6afe4defa748de89eac90ba1062232bb5aA. Unique TensorFlower DCHECK(tag() != REP_OUT_OF_LINE || (*as64()->dims_).size() == ndims_byte()); 1129ccc4b6afe4defa748de89eac90ba1062232bb5aA. Unique TensorFlower return ndims_byte(); 113df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower } 114db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 115db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// \brief Returns the number of elements in dimension `d`. 116db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// REQUIRES: `0 <= d < dims()` 117db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg // TODO(touts): Rename to `dimension()` to match 118db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg // `Eigen::Tensor::dimension()`? 1199ccc4b6afe4defa748de89eac90ba1062232bb5aA. Unique TensorFlower int64 dim_size(int d) const; 120db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 121db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Returns sizes of all dimensions. 122df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower gtl::InlinedVector<int64, 4> dim_sizes() const; 123db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 124db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// \brief Returns the number of elements in the tensor. 125db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// 126db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// We use `int64` and not `size_t` to be compatible with `Eigen::Tensor` 127db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// which uses `ptrdiff_t`. 128db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg int64 num_elements() const { return num_elements_; } 129db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 130db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Returns true if `*this` and `b` have the same sizes. Ignores 131db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// dimension names. 132db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg bool IsSameSize(const TensorShape& b) const; 133db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg bool operator==(const TensorShape& b) const { return IsSameSize(b); } 13412b36c655359319c1ad31907d407bba3c594fee7A. Unique TensorFlower bool operator!=(const TensorShape& b) const { return !IsSameSize(b); } 135db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 136db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Fill `*proto` from `*this`. 137db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg void AsProto(TensorShapeProto* proto) const; 138db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 139db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Fill `*dsizes` from `*this`. 140db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg template <int NDIMS> 141db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg Eigen::DSizes<Eigen::DenseIndex, NDIMS> AsEigenDSizes() const; 142db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 143db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// Same as `AsEigenDSizes()` but allows for `NDIMS > dims()` -- in 144db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// which case we pad the rest of the sizes with 1. 145db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg template <int NDIMS> 146db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg Eigen::DSizes<Eigen::DenseIndex, NDIMS> AsEigenDSizesWithPadding() const; 147db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 148db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// For iterating through the dimensions. 149db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg TensorShapeIter begin() const; 150db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg TensorShapeIter end() const; 151db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 152db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// For error messages. 153db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg string DebugString() const; 154db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 155d552be23658b3bdd1b7dedd34f25631773e81dffGeoffrey Irving /// Same as `TensorShape(proto).DebugString()` but doesn't crash for 156db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// invalid protos. 157d552be23658b3bdd1b7dedd34f25631773e81dffGeoffrey Irving static string DebugString(const TensorShapeProto& proto); 158d552be23658b3bdd1b7dedd34f25631773e81dffGeoffrey Irving 159df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower void DumpRep() const; // XXX 160e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6Geoffrey Irving 161db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg private: 162b76812c8a84c0efd45342121bfc1cff2b6bb1051A. Unique TensorFlower void DestructorOutOfLine(); 1639934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower void ClearAllButDataType(); 164df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower void SlowCopyFrom(const TensorShape& b); 165df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 166df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower void RecomputeNumElements(); 167df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 168821920c1f25968f5dfcd2f8999b293ebedf85957A. Unique TensorFlower void CheckDimsEqual(int NDIMS) const; 169821920c1f25968f5dfcd2f8999b293ebedf85957A. Unique TensorFlower void CheckDimsAtLeast(int NDIMS) const; 170821920c1f25968f5dfcd2f8999b293ebedf85957A. Unique TensorFlower 171e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6Geoffrey Irving // Used by AddDim and MakeShapeHelper. Does no error checking. 172e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6Geoffrey Irving void UnsafeAddDim(int64 size, int64 new_num_elements); 173e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6Geoffrey Irving 174e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6Geoffrey Irving // For use by TensorShapeUtils::MakeShape 175e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6Geoffrey Irving template <class T> 176e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6Geoffrey Irving friend Status MakeShapeHelper(const T*, int64, TensorShape*); 177e8ee5286a686c6fc3057ba7cf9ba9ef7003789a6Geoffrey Irving 178df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // We use 16 bytes to represent a TensorShape. Because we need to 179df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // be able to support full 64-bit dimension sizes and an arbitrary 180df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // number of dimensions for a Tensor, but most tensor dimensions are 181df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // significantly smaller than 64 bits and most tensors are 1, 2, or 3 182df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // dimensions, we have several representations. 1839934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower // Rep16: Supports up to 6 dimensions where each dimension is < 2^16 184df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // Rep32: Supports up to 3 dimensions where each dimension is < 2^32 1851bcebcc665e7e9c280be65899002fd3d5a7456a5Geoffrey Irving // Rep64: Supports arbitrary dimensionality, 64-bit dimensions using 186df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // an out of line vector. 187df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower struct Rep16 { 1889934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower int16 dims_[6]; 189df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower }; 190df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower struct Rep32 { 191df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower int32 dims_[3]; 192df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower }; 193df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower struct Rep64 { 194df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower gtl::InlinedVector<int64, 4>* dims_; 195df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower }; 196df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 197df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower static const int64 kMaxRep16 = 32768; 198df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower static const int64 kMaxRep32 = (1ull << 31) - 1; 199df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 200df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower uint8* buf() { return &u_.buf[0]; } 201df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower const uint8* buf() const { return &u_.buf[0]; } 202df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 203df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower Rep16* as16() { return reinterpret_cast<Rep16*>(buf()); } 204df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower Rep32* as32() { return reinterpret_cast<Rep32*>(buf()); } 205df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower Rep64* as64() { return reinterpret_cast<Rep64*>(buf()); } 206df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 207df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower const Rep16* as16() const { return reinterpret_cast<const Rep16*>(buf()); } 208df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower const Rep32* as32() const { return reinterpret_cast<const Rep32*>(buf()); } 209df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower const Rep64* as64() const { return reinterpret_cast<const Rep64*>(buf()); } 210df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 211df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower enum RepTag { REP16 = 0, REP32 = 1, REP_OUT_OF_LINE = 2 }; 212df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 2139934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower // Since we have a convenient extra byte available, we allow the 2149934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower // Tensor class to store an 8-bit value in this extra storage. This 2159934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower // allows it to store the Tensor's datatype enum value here and avoid 2169934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower // an extra word of storage. 2179934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower friend class Tensor; 2189934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower friend class TensorShapeTestHelper; 2199934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower DataType data_type() const { return static_cast<DataType>(buf()[13]); } 2209934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower void set_data_type(DataType dt) { 2219934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower // We only have 8 bits available to store DataType, so make sure it fits 222f4002dd3cb62d64053bc6097a70f83c718c24af2A. Unique TensorFlower DCHECK_LT(static_cast<uint32>(dt), 256u); 2239934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower buf()[13] = static_cast<uint8>(dt); 2249934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower } 2259934b9c6841ee56368c7cb1d10053f68a02680baA. Unique TensorFlower 226df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // We store the number of dimensions in byte 14, and the RepTag in byte 15. 227df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // Bytes [0..13] vary depending on the representation 228df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower uint8 ndims_byte() const { return buf()[14]; } 229df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower void set_ndims_byte(uint8 nd) { buf()[14] = nd; } 230df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 231df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower RepTag tag() const { return static_cast<RepTag>(buf()[15]); } 232df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower void set_tag(RepTag tag) { buf()[15] = static_cast<uint8>(tag); } 233df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 234df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower union { 235df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower uint8 buf[16]; 236df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // Force data to be aligned enough for a pointer. 237df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower Rep64* unused_aligner; 238df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower } u_; 239db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg int64 num_elements_; 240db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg}; 241db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 242120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower/// Represents the value of one dimension in a TensorShape. 243db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergstruct TensorShapeDim { 244db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg explicit TensorShapeDim(int64 s) : size(s) {} 245d33346a801181cb601a4cfc95f1087e165b19703Vijay Vasudevan int64 size; 246db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg}; 247db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 248120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower// START_SKIP_DOXYGEN 249db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergclass TensorShapeIter { 250db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg public: 251db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg TensorShapeIter(const TensorShape* shape, int d) : shape_(shape), d_(d) {} 252db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg bool operator==(const TensorShapeIter& rhs) { 253db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg DCHECK(shape_ == rhs.shape_); 254db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg return d_ == rhs.d_; 255db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg } 256db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg bool operator!=(const TensorShapeIter& rhs) { 257db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg DCHECK(shape_ == rhs.shape_); 258db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg return d_ != rhs.d_; 259db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg } 260db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg void operator++() { ++d_; } 261db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg TensorShapeDim operator*() { return TensorShapeDim(shape_->dim_size(d_)); } 262db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 263db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg private: 264db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg const TensorShape* shape_; 265db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg int d_; 266db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg}; 267120c3f11f857ce6da7ae90b3eab943896499dca2A. Unique TensorFlower// END_SKIP_DOXYGEN 268db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 269db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg/// \brief Static helper routines for `TensorShape`. Includes a few common 270db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg/// predicates on a tensor shape. 271db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergclass TensorShapeUtils { 272db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg public: 273db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg static bool IsScalar(const TensorShape& shape) { return shape.dims() == 0; } 274db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 275db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg static bool IsVector(const TensorShape& shape) { return shape.dims() == 1; } 276db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 277db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg static bool IsVectorOrHigher(const TensorShape& shape) { 278db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg return shape.dims() >= 1; 279db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg } 280db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 281db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg static bool IsMatrix(const TensorShape& shape) { return shape.dims() == 2; } 282db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 283053fc50b2cbb1979cbed1662c3d964c36fdafecdA. Unique TensorFlower static bool IsSquareMatrix(const TensorShape& shape) { 284053fc50b2cbb1979cbed1662c3d964c36fdafecdA. Unique TensorFlower return shape.dims() == 2 && shape.dim_size(0) == shape.dim_size(1); 285053fc50b2cbb1979cbed1662c3d964c36fdafecdA. Unique TensorFlower } 286053fc50b2cbb1979cbed1662c3d964c36fdafecdA. Unique TensorFlower 287db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg static bool IsMatrixOrHigher(const TensorShape& shape) { 288db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg return shape.dims() >= 2; 289db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg } 290db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 291db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// \brief Returns a `TensorShape` whose dimensions are 292db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg /// `dims[0]`, `dims[1]`, ..., `dims[n-1]`. 29396a1afa21c59999c68887550b0c8c27cdf171339David G. Andersen static Status MakeShape(const int32* dims, int64 n, TensorShape* out); 29496a1afa21c59999c68887550b0c8c27cdf171339David G. Andersen static Status MakeShape(const int64* dims, int64 n, TensorShape* out); 2959d6b7680cfcc5b784401d17fef997f0c089038b1A. Unique TensorFlower static Status MakeShape(gtl::ArraySlice<int32> shape, TensorShape* out); 2969d6b7680cfcc5b784401d17fef997f0c089038b1A. Unique TensorFlower static Status MakeShape(gtl::ArraySlice<int64> shape, TensorShape* out); 297db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 298725e968a934419eec45b9acaf4bf8dc5f5f0574eGeoffrey Irving static string ShapeListString(const gtl::ArraySlice<TensorShape>& shapes); 299db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 300b5388091998dbeb6641b5d29dbceb825ee359acdA. Unique TensorFlower /// \brief Returns true iff `shape` starts with `prefix`. 301b5388091998dbeb6641b5d29dbceb825ee359acdA. Unique TensorFlower static bool StartsWith(const TensorShape& shape, const TensorShape& prefix); 302b5388091998dbeb6641b5d29dbceb825ee359acdA. Unique TensorFlower 303b5388091998dbeb6641b5d29dbceb825ee359acdA. Unique TensorFlower /// \brief Returns true iff `shape` ends with `suffix`. 304b5388091998dbeb6641b5d29dbceb825ee359acdA. Unique TensorFlower static bool EndsWith(const TensorShape& shape, const TensorShape& suffix); 305db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg}; 306db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 307db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg// ---------------------------------------------------------------------------- 308db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg// Template method implementation details below 309db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg// ---------------------------------------------------------------------------- 310db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 311db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergtemplate <int NDIMS> 312db7478e8998f7703c57a75a950c905ec0cb59d7bJosh LevenbergEigen::DSizes<Eigen::DenseIndex, NDIMS> TensorShape::AsEigenDSizes() const { 313821920c1f25968f5dfcd2f8999b293ebedf85957A. Unique TensorFlower CheckDimsEqual(NDIMS); 314db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg return AsEigenDSizesWithPadding<NDIMS>(); 315db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg} 316db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 317db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenbergtemplate <int NDIMS> 318db7478e8998f7703c57a75a950c905ec0cb59d7bJosh LevenbergEigen::DSizes<Eigen::DenseIndex, NDIMS> TensorShape::AsEigenDSizesWithPadding() 319db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg const { 320821920c1f25968f5dfcd2f8999b293ebedf85957A. Unique TensorFlower CheckDimsAtLeast(NDIMS); 3214d9ec5ece5771a1982352574ce2cad587644fadaDavid G. Andersen static_assert(NDIMS <= TensorShape::MaxDimensions(), "Too many dimensions"); 322db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg Eigen::DSizes<Eigen::DenseIndex, NDIMS> dsizes; 323db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg for (int d = 0; d < dims(); d++) { 324db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg dsizes[d] = dim_size(d); 325db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg } 326db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg for (int d = dims(); d < NDIMS; d++) { 327db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg dsizes[d] = 1; 328db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg } 329db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg return dsizes; 330db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg} 331db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 332df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower// ---------------------------------------------------------------------------- 333df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower// Inlining of some performance critical routines 334df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower// ---------------------------------------------------------------------------- 335df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 336df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlowerinline TensorShape::TensorShape(const TensorShape& b) { 337df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower num_elements_ = b.num_elements_; 338df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower if (b.tag() != REP_OUT_OF_LINE) { 339df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower memcpy(buf(), b.buf(), sizeof(u_.buf)); 340df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // memcpy above Implicitly does: 341df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // set_ndims_byte(b.ndims_byte()); 342df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // set_tag(b.tag()); 343df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower } else { 344df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower set_tag(REP16); // So that SlowCopyFrom does not try to deallocate 345df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower SlowCopyFrom(b); 346df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower } 347df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower} 348df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 349f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlowerinline TensorShape::TensorShape(TensorShape&& b) { 350f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower num_elements_ = b.num_elements_; 351f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower memcpy(buf(), b.buf(), sizeof(u_.buf)); 352f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // memcpy above Implicitly does: 353f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // set_ndims_byte(b.ndims_byte()); 354f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // set_tag(b.tag()); 355f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower b.set_tag(REP16); // other shape no longer owns out-of-line data, if any. 356f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower} 357f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower 358df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlowerinline TensorShape::~TensorShape() { 359df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower if (tag() == REP_OUT_OF_LINE) { 360b76812c8a84c0efd45342121bfc1cff2b6bb1051A. Unique TensorFlower DestructorOutOfLine(); 361df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower } 362df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower} 363df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 364df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlowerinline void TensorShape::operator=(const TensorShape& b) { 365df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower num_elements_ = b.num_elements_; 366df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower if (tag() != REP_OUT_OF_LINE && b.tag() != REP_OUT_OF_LINE) { 367df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower memcpy(buf(), b.buf(), sizeof(u_.buf)); 368df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // memcpy above implicitly also does: 369df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // set_tag(b.tag()); 370df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower // set_ndims_byte(b.ndims_byte()); 371df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower } else { 372df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower SlowCopyFrom(b); 373df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower } 374df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower} 375df66b9fe049cb17e58454f309b662bdaf0d14fdbA. Unique TensorFlower 376f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlowerinline void TensorShape::operator=(TensorShape&& b) { 377f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower if (tag() == REP_OUT_OF_LINE) { 378f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower DestructorOutOfLine(); 379f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower } 380f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower num_elements_ = b.num_elements_; 381f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower memcpy(buf(), b.buf(), sizeof(u_.buf)); 382f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // memcpy above Implicitly does: 383f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // set_ndims_byte(b.ndims_byte()); 384f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower // set_tag(b.tag()); 385f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower b.set_tag(REP16); // other shape no longer owns out-of-line data, if any. 386f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower} 387f7a662e595f1631c12d15173344ee0f50d2cd9f8A. Unique TensorFlower 388db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg} // namespace tensorflow 389db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg 390db7478e8998f7703c57a75a950c905ec0cb59d7bJosh Levenberg#endif // TENSORFLOW_CORE_FRAMEWORK_TENSOR_SHAPE_H_ 391