• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_CORE_UTIL_SPARSE_DIM_COMPARATOR_H_
17 #define TENSORFLOW_CORE_UTIL_SPARSE_DIM_COMPARATOR_H_
18 
19 #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
20 #include "tensorflow/core/framework/bounds_check.h"
21 #include "tensorflow/core/lib/gtl/array_slice.h"
22 #include "tensorflow/core/platform/logging.h"
23 #include "tensorflow/core/platform/types.h"
24 
25 namespace tensorflow {
26 namespace sparse {
27 
28 /////////////////
29 // DimComparator
30 /////////////////
31 //
32 // Helper class, mainly used by the IndexSortOrder. This comparator
33 // can be passed to e.g. std::sort, or any other sorter, to sort two
34 // rows of an index matrix according to the dimension(s) of interest.
35 // The dimensions to sort by are passed to the constructor as "order".
36 //
37 // Example: if given index matrix IX, two rows ai and bi, and order = {2,1}.
38 // operator() compares
39 //    IX(ai,2) < IX(bi,2).
40 // If IX(ai,2) == IX(bi,2), it compares
41 //    IX(ai,1) < IX(bi,1).
42 //
43 // This can be used to sort a vector of row indices into IX according to
44 // the values in IX in particular columns (dimensions) of interest.
45 class DimComparator {
46  public:
47   typedef typename gtl::ArraySlice<int64> VarDimArray;
48 
DimComparator(const TTypes<int64>::Matrix & ix,const VarDimArray & order,const VarDimArray & shape)49   DimComparator(const TTypes<int64>::Matrix& ix, const VarDimArray& order,
50                 const VarDimArray& shape)
51       : ix_(ix), order_(order), dims_(shape.size()) {
52     DCHECK_GT(order.size(), size_t{0}) << "Must order using at least one index";
53     DCHECK_LE(order.size(), shape.size()) << "Can only sort up to dims";
54     for (size_t d = 0; d < order.size(); ++d) {
55       DCHECK_GE(order[d], 0);
56       DCHECK_LT(order[d], shape.size());
57     }
58   }
59 
operator()60   inline bool operator()(const int64 i, const int64 j) const {
61     for (int di = 0; di < dims_; ++di) {
62       const int64 d = order_[di];
63       if (ix_(i, d) < ix_(j, d)) return true;
64       if (ix_(i, d) > ix_(j, d)) return false;
65     }
66     return false;
67   }
68 
69   // Compares two indices taken from corresponding index matrices, using the
70   // standard, row-major (or lexicographic) order.  Useful for cases that need
71   // to distinguish between all three orderings (<, ==, >).
cmp(const TTypes<int64>::ConstMatrix & a_idx,const TTypes<int64>::ConstMatrix & b_idx,const int64 a_row,const int64 b_row,const int dims)72   inline static int cmp(const TTypes<int64>::ConstMatrix& a_idx,
73                         const TTypes<int64>::ConstMatrix& b_idx,
74                         const int64 a_row, const int64 b_row, const int dims) {
75     for (int d = 0; d < dims; ++d) {
76       const int64 a = a_idx(a_row, d);
77       const int64 b = b_idx(b_row, d);
78       if (a < b) {
79         return -1;
80       } else if (a > b) {
81         return 1;
82       }
83     }
84     return 0;
85   }
86 
87  protected:
88   const TTypes<int64>::Matrix ix_;
89   const VarDimArray order_;
90   const int dims_;
91   const std::vector<int64>* ix_order_;
92 };
93 
94 template <int ORDER_DIM>
95 class FixedDimComparator : DimComparator {
96  public:
FixedDimComparator(const TTypes<int64>::Matrix & ix,const VarDimArray & order,const VarDimArray & shape)97   FixedDimComparator(const TTypes<int64>::Matrix& ix, const VarDimArray& order,
98                      const VarDimArray& shape)
99       : DimComparator(ix, order, shape) {
100     DCHECK_EQ(order.size(), ORDER_DIM);
101   }
operator()102   inline bool operator()(const int64 i, const int64 j) const {
103     bool value = false;
104     for (int di = 0; di < ORDER_DIM; ++di) {
105       const int64 d = order_[di];
106       if (ix_(i, d) < ix_(j, d)) {
107         value = true;
108         break;
109       }
110       if (ix_(i, d) > ix_(j, d)) break;
111     }
112     return value;
113   }
114 };
115 
116 }  // namespace sparse
117 }  // namespace tensorflow
118 
119 #endif  // TENSORFLOW_CORE_UTIL_SPARSE_DIM_COMPARATOR_H_
120