Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- Math.h - PBQP Vector and Matrix classes ------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
 
9
#ifndef LLVM_CODEGEN_PBQP_MATH_H
10
#define LLVM_CODEGEN_PBQP_MATH_H
11
 
12
#include "llvm/ADT/Hashing.h"
13
#include "llvm/ADT/STLExtras.h"
14
#include <algorithm>
15
#include <cassert>
16
#include <functional>
17
#include <memory>
18
 
19
namespace llvm {
20
namespace PBQP {
21
 
22
using PBQPNum = float;
23
 
24
/// PBQP Vector class.
25
class Vector {
26
  friend hash_code hash_value(const Vector &);
27
 
28
public:
29
  /// Construct a PBQP vector of the given size.
30
  explicit Vector(unsigned Length)
31
    : Length(Length), Data(std::make_unique<PBQPNum []>(Length)) {}
32
 
33
  /// Construct a PBQP vector with initializer.
34
  Vector(unsigned Length, PBQPNum InitVal)
35
    : Length(Length), Data(std::make_unique<PBQPNum []>(Length)) {
36
    std::fill(Data.get(), Data.get() + Length, InitVal);
37
  }
38
 
39
  /// Copy construct a PBQP vector.
40
  Vector(const Vector &V)
41
    : Length(V.Length), Data(std::make_unique<PBQPNum []>(Length)) {
42
    std::copy(V.Data.get(), V.Data.get() + Length, Data.get());
43
  }
44
 
45
  /// Move construct a PBQP vector.
46
  Vector(Vector &&V)
47
    : Length(V.Length), Data(std::move(V.Data)) {
48
    V.Length = 0;
49
  }
50
 
51
  /// Comparison operator.
52
  bool operator==(const Vector &V) const {
53
    assert(Length != 0 && Data && "Invalid vector");
54
    if (Length != V.Length)
55
      return false;
56
    return std::equal(Data.get(), Data.get() + Length, V.Data.get());
57
  }
58
 
59
  /// Return the length of the vector
60
  unsigned getLength() const {
61
    assert(Length != 0 && Data && "Invalid vector");
62
    return Length;
63
  }
64
 
65
  /// Element access.
66
  PBQPNum& operator[](unsigned Index) {
67
    assert(Length != 0 && Data && "Invalid vector");
68
    assert(Index < Length && "Vector element access out of bounds.");
69
    return Data[Index];
70
  }
71
 
72
  /// Const element access.
73
  const PBQPNum& operator[](unsigned Index) const {
74
    assert(Length != 0 && Data && "Invalid vector");
75
    assert(Index < Length && "Vector element access out of bounds.");
76
    return Data[Index];
77
  }
78
 
79
  /// Add another vector to this one.
80
  Vector& operator+=(const Vector &V) {
81
    assert(Length != 0 && Data && "Invalid vector");
82
    assert(Length == V.Length && "Vector length mismatch.");
83
    std::transform(Data.get(), Data.get() + Length, V.Data.get(), Data.get(),
84
                   std::plus<PBQPNum>());
85
    return *this;
86
  }
87
 
88
  /// Returns the index of the minimum value in this vector
89
  unsigned minIndex() const {
90
    assert(Length != 0 && Data && "Invalid vector");
91
    return std::min_element(Data.get(), Data.get() + Length) - Data.get();
92
  }
93
 
94
private:
95
  unsigned Length;
96
  std::unique_ptr<PBQPNum []> Data;
97
};
98
 
99
/// Return a hash_value for the given vector.
100
inline hash_code hash_value(const Vector &V) {
101
  unsigned *VBegin = reinterpret_cast<unsigned*>(V.Data.get());
102
  unsigned *VEnd = reinterpret_cast<unsigned*>(V.Data.get() + V.Length);
103
  return hash_combine(V.Length, hash_combine_range(VBegin, VEnd));
104
}
105
 
106
/// Output a textual representation of the given vector on the given
107
///        output stream.
108
template <typename OStream>
109
OStream& operator<<(OStream &OS, const Vector &V) {
110
  assert((V.getLength() != 0) && "Zero-length vector badness.");
111
 
112
  OS << "[ " << V[0];
113
  for (unsigned i = 1; i < V.getLength(); ++i)
114
    OS << ", " << V[i];
115
  OS << " ]";
116
 
117
  return OS;
118
}
119
 
120
/// PBQP Matrix class
121
class Matrix {
122
private:
123
  friend hash_code hash_value(const Matrix &);
124
 
125
public:
126
  /// Construct a PBQP Matrix with the given dimensions.
127
  Matrix(unsigned Rows, unsigned Cols) :
128
    Rows(Rows), Cols(Cols), Data(std::make_unique<PBQPNum []>(Rows * Cols)) {
129
  }
130
 
131
  /// Construct a PBQP Matrix with the given dimensions and initial
132
  /// value.
133
  Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal)
134
    : Rows(Rows), Cols(Cols),
135
      Data(std::make_unique<PBQPNum []>(Rows * Cols)) {
136
    std::fill(Data.get(), Data.get() + (Rows * Cols), InitVal);
137
  }
138
 
139
  /// Copy construct a PBQP matrix.
140
  Matrix(const Matrix &M)
141
    : Rows(M.Rows), Cols(M.Cols),
142
      Data(std::make_unique<PBQPNum []>(Rows * Cols)) {
143
    std::copy(M.Data.get(), M.Data.get() + (Rows * Cols), Data.get());
144
  }
145
 
146
  /// Move construct a PBQP matrix.
147
  Matrix(Matrix &&M)
148
    : Rows(M.Rows), Cols(M.Cols), Data(std::move(M.Data)) {
149
    M.Rows = M.Cols = 0;
150
  }
151
 
152
  /// Comparison operator.
153
  bool operator==(const Matrix &M) const {
154
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
155
    if (Rows != M.Rows || Cols != M.Cols)
156
      return false;
157
    return std::equal(Data.get(), Data.get() + (Rows * Cols), M.Data.get());
158
  }
159
 
160
  /// Return the number of rows in this matrix.
161
  unsigned getRows() const {
162
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
163
    return Rows;
164
  }
165
 
166
  /// Return the number of cols in this matrix.
167
  unsigned getCols() const {
168
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
169
    return Cols;
170
  }
171
 
172
  /// Matrix element access.
173
  PBQPNum* operator[](unsigned R) {
174
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
175
    assert(R < Rows && "Row out of bounds.");
176
    return Data.get() + (R * Cols);
177
  }
178
 
179
  /// Matrix element access.
180
  const PBQPNum* operator[](unsigned R) const {
181
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
182
    assert(R < Rows && "Row out of bounds.");
183
    return Data.get() + (R * Cols);
184
  }
185
 
186
  /// Returns the given row as a vector.
187
  Vector getRowAsVector(unsigned R) const {
188
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
189
    Vector V(Cols);
190
    for (unsigned C = 0; C < Cols; ++C)
191
      V[C] = (*this)[R][C];
192
    return V;
193
  }
194
 
195
  /// Returns the given column as a vector.
196
  Vector getColAsVector(unsigned C) const {
197
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
198
    Vector V(Rows);
199
    for (unsigned R = 0; R < Rows; ++R)
200
      V[R] = (*this)[R][C];
201
    return V;
202
  }
203
 
204
  /// Matrix transpose.
205
  Matrix transpose() const {
206
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
207
    Matrix M(Cols, Rows);
208
    for (unsigned r = 0; r < Rows; ++r)
209
      for (unsigned c = 0; c < Cols; ++c)
210
        M[c][r] = (*this)[r][c];
211
    return M;
212
  }
213
 
214
  /// Add the given matrix to this one.
215
  Matrix& operator+=(const Matrix &M) {
216
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
217
    assert(Rows == M.Rows && Cols == M.Cols &&
218
           "Matrix dimensions mismatch.");
219
    std::transform(Data.get(), Data.get() + (Rows * Cols), M.Data.get(),
220
                   Data.get(), std::plus<PBQPNum>());
221
    return *this;
222
  }
223
 
224
  Matrix operator+(const Matrix &M) {
225
    assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
226
    Matrix Tmp(*this);
227
    Tmp += M;
228
    return Tmp;
229
  }
230
 
231
private:
232
  unsigned Rows, Cols;
233
  std::unique_ptr<PBQPNum []> Data;
234
};
235
 
236
/// Return a hash_code for the given matrix.
237
inline hash_code hash_value(const Matrix &M) {
238
  unsigned *MBegin = reinterpret_cast<unsigned*>(M.Data.get());
239
  unsigned *MEnd =
240
    reinterpret_cast<unsigned*>(M.Data.get() + (M.Rows * M.Cols));
241
  return hash_combine(M.Rows, M.Cols, hash_combine_range(MBegin, MEnd));
242
}
243
 
244
/// Output a textual representation of the given matrix on the given
245
///        output stream.
246
template <typename OStream>
247
OStream& operator<<(OStream &OS, const Matrix &M) {
248
  assert((M.getRows() != 0) && "Zero-row matrix badness.");
249
  for (unsigned i = 0; i < M.getRows(); ++i)
250
    OS << M.getRowAsVector(i) << "\n";
251
  return OS;
252
}
253
 
254
template <typename Metadata>
255
class MDVector : public Vector {
256
public:
257
  MDVector(const Vector &v) : Vector(v), md(*this) {}
258
  MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { }
259
 
260
  const Metadata& getMetadata() const { return md; }
261
 
262
private:
263
  Metadata md;
264
};
265
 
266
template <typename Metadata>
267
inline hash_code hash_value(const MDVector<Metadata> &V) {
268
  return hash_value(static_cast<const Vector&>(V));
269
}
270
 
271
template <typename Metadata>
272
class MDMatrix : public Matrix {
273
public:
274
  MDMatrix(const Matrix &m) : Matrix(m), md(*this) {}
275
  MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { }
276
 
277
  const Metadata& getMetadata() const { return md; }
278
 
279
private:
280
  Metadata md;
281
};
282
 
283
template <typename Metadata>
284
inline hash_code hash_value(const MDMatrix<Metadata> &M) {
285
  return hash_value(static_cast<const Matrix&>(M));
286
}
287
 
288
} // end namespace PBQP
289
} // end namespace llvm
290
 
291
#endif // LLVM_CODEGEN_PBQP_MATH_H