File indexing completed on 2026-05-10 08:43:26
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CODEGEN_PBQP_MATH_H
0010 #define LLVM_CODEGEN_PBQP_MATH_H
0011
0012 #include "llvm/ADT/Hashing.h"
0013 #include "llvm/ADT/STLExtras.h"
0014 #include <algorithm>
0015 #include <cassert>
0016 #include <functional>
0017 #include <memory>
0018
0019 namespace llvm {
0020 namespace PBQP {
0021
0022 using PBQPNum = float;
0023
0024
0025 class Vector {
0026 friend hash_code hash_value(const Vector &);
0027
0028 public:
0029
0030 explicit Vector(unsigned Length)
0031 : Length(Length), Data(std::make_unique<PBQPNum []>(Length)) {}
0032
0033
0034 Vector(unsigned Length, PBQPNum InitVal)
0035 : Length(Length), Data(std::make_unique<PBQPNum []>(Length)) {
0036 std::fill(Data.get(), Data.get() + Length, InitVal);
0037 }
0038
0039
0040 Vector(const Vector &V)
0041 : Length(V.Length), Data(std::make_unique<PBQPNum []>(Length)) {
0042 std::copy(V.Data.get(), V.Data.get() + Length, Data.get());
0043 }
0044
0045
0046 Vector(Vector &&V)
0047 : Length(V.Length), Data(std::move(V.Data)) {
0048 V.Length = 0;
0049 }
0050
0051
0052 bool operator==(const Vector &V) const {
0053 assert(Length != 0 && Data && "Invalid vector");
0054 if (Length != V.Length)
0055 return false;
0056 return std::equal(Data.get(), Data.get() + Length, V.Data.get());
0057 }
0058
0059
0060 unsigned getLength() const {
0061 assert(Length != 0 && Data && "Invalid vector");
0062 return Length;
0063 }
0064
0065
0066 PBQPNum& operator[](unsigned Index) {
0067 assert(Length != 0 && Data && "Invalid vector");
0068 assert(Index < Length && "Vector element access out of bounds.");
0069 return Data[Index];
0070 }
0071
0072
0073 const PBQPNum& operator[](unsigned Index) const {
0074 assert(Length != 0 && Data && "Invalid vector");
0075 assert(Index < Length && "Vector element access out of bounds.");
0076 return Data[Index];
0077 }
0078
0079
0080 Vector& operator+=(const Vector &V) {
0081 assert(Length != 0 && Data && "Invalid vector");
0082 assert(Length == V.Length && "Vector length mismatch.");
0083 std::transform(Data.get(), Data.get() + Length, V.Data.get(), Data.get(),
0084 std::plus<PBQPNum>());
0085 return *this;
0086 }
0087
0088
0089 unsigned minIndex() const {
0090 assert(Length != 0 && Data && "Invalid vector");
0091 return std::min_element(Data.get(), Data.get() + Length) - Data.get();
0092 }
0093
0094 private:
0095 unsigned Length;
0096 std::unique_ptr<PBQPNum []> Data;
0097 };
0098
0099
0100 inline hash_code hash_value(const Vector &V) {
0101 unsigned *VBegin = reinterpret_cast<unsigned*>(V.Data.get());
0102 unsigned *VEnd = reinterpret_cast<unsigned*>(V.Data.get() + V.Length);
0103 return hash_combine(V.Length, hash_combine_range(VBegin, VEnd));
0104 }
0105
0106
0107
0108 template <typename OStream>
0109 OStream& operator<<(OStream &OS, const Vector &V) {
0110 assert((V.getLength() != 0) && "Zero-length vector badness.");
0111
0112 OS << "[ " << V[0];
0113 for (unsigned i = 1; i < V.getLength(); ++i)
0114 OS << ", " << V[i];
0115 OS << " ]";
0116
0117 return OS;
0118 }
0119
0120
0121 class Matrix {
0122 private:
0123 friend hash_code hash_value(const Matrix &);
0124
0125 public:
0126
0127 Matrix(unsigned Rows, unsigned Cols) :
0128 Rows(Rows), Cols(Cols), Data(std::make_unique<PBQPNum []>(Rows * Cols)) {
0129 }
0130
0131
0132
0133 Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal)
0134 : Rows(Rows), Cols(Cols),
0135 Data(std::make_unique<PBQPNum []>(Rows * Cols)) {
0136 std::fill(Data.get(), Data.get() + (Rows * Cols), InitVal);
0137 }
0138
0139
0140 Matrix(const Matrix &M)
0141 : Rows(M.Rows), Cols(M.Cols),
0142 Data(std::make_unique<PBQPNum []>(Rows * Cols)) {
0143 std::copy(M.Data.get(), M.Data.get() + (Rows * Cols), Data.get());
0144 }
0145
0146
0147 Matrix(Matrix &&M)
0148 : Rows(M.Rows), Cols(M.Cols), Data(std::move(M.Data)) {
0149 M.Rows = M.Cols = 0;
0150 }
0151
0152
0153 bool operator==(const Matrix &M) const {
0154 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0155 if (Rows != M.Rows || Cols != M.Cols)
0156 return false;
0157 return std::equal(Data.get(), Data.get() + (Rows * Cols), M.Data.get());
0158 }
0159
0160
0161 unsigned getRows() const {
0162 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0163 return Rows;
0164 }
0165
0166
0167 unsigned getCols() const {
0168 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0169 return Cols;
0170 }
0171
0172
0173 PBQPNum* operator[](unsigned R) {
0174 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0175 assert(R < Rows && "Row out of bounds.");
0176 return Data.get() + (R * Cols);
0177 }
0178
0179
0180 const PBQPNum* operator[](unsigned R) const {
0181 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0182 assert(R < Rows && "Row out of bounds.");
0183 return Data.get() + (R * Cols);
0184 }
0185
0186
0187 Vector getRowAsVector(unsigned R) const {
0188 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0189 Vector V(Cols);
0190 for (unsigned C = 0; C < Cols; ++C)
0191 V[C] = (*this)[R][C];
0192 return V;
0193 }
0194
0195
0196 Vector getColAsVector(unsigned C) const {
0197 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0198 Vector V(Rows);
0199 for (unsigned R = 0; R < Rows; ++R)
0200 V[R] = (*this)[R][C];
0201 return V;
0202 }
0203
0204
0205 Matrix transpose() const {
0206 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0207 Matrix M(Cols, Rows);
0208 for (unsigned r = 0; r < Rows; ++r)
0209 for (unsigned c = 0; c < Cols; ++c)
0210 M[c][r] = (*this)[r][c];
0211 return M;
0212 }
0213
0214
0215 Matrix& operator+=(const Matrix &M) {
0216 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0217 assert(Rows == M.Rows && Cols == M.Cols &&
0218 "Matrix dimensions mismatch.");
0219 std::transform(Data.get(), Data.get() + (Rows * Cols), M.Data.get(),
0220 Data.get(), std::plus<PBQPNum>());
0221 return *this;
0222 }
0223
0224 Matrix operator+(const Matrix &M) {
0225 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
0226 Matrix Tmp(*this);
0227 Tmp += M;
0228 return Tmp;
0229 }
0230
0231 private:
0232 unsigned Rows, Cols;
0233 std::unique_ptr<PBQPNum []> Data;
0234 };
0235
0236
0237 inline hash_code hash_value(const Matrix &M) {
0238 unsigned *MBegin = reinterpret_cast<unsigned*>(M.Data.get());
0239 unsigned *MEnd =
0240 reinterpret_cast<unsigned*>(M.Data.get() + (M.Rows * M.Cols));
0241 return hash_combine(M.Rows, M.Cols, hash_combine_range(MBegin, MEnd));
0242 }
0243
0244
0245
0246 template <typename OStream>
0247 OStream& operator<<(OStream &OS, const Matrix &M) {
0248 assert((M.getRows() != 0) && "Zero-row matrix badness.");
0249 for (unsigned i = 0; i < M.getRows(); ++i)
0250 OS << M.getRowAsVector(i) << "\n";
0251 return OS;
0252 }
0253
0254 template <typename Metadata>
0255 class MDVector : public Vector {
0256 public:
0257 MDVector(const Vector &v) : Vector(v), md(*this) {}
0258 MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { }
0259
0260 const Metadata& getMetadata() const { return md; }
0261
0262 private:
0263 Metadata md;
0264 };
0265
0266 template <typename Metadata>
0267 inline hash_code hash_value(const MDVector<Metadata> &V) {
0268 return hash_value(static_cast<const Vector&>(V));
0269 }
0270
0271 template <typename Metadata>
0272 class MDMatrix : public Matrix {
0273 public:
0274 MDMatrix(const Matrix &m) : Matrix(m), md(*this) {}
0275 MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { }
0276
0277 const Metadata& getMetadata() const { return md; }
0278
0279 private:
0280 Metadata md;
0281 };
0282
0283 template <typename Metadata>
0284 inline hash_code hash_value(const MDMatrix<Metadata> &M) {
0285 return hash_value(static_cast<const Matrix&>(M));
0286 }
0287
0288 }
0289 }
0290
0291 #endif