- //===- Math.h - PBQP Vector and Matrix classes ------------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CODEGEN_PBQP_MATH_H 
- #define LLVM_CODEGEN_PBQP_MATH_H 
-   
- #include "llvm/ADT/Hashing.h" 
- #include "llvm/ADT/STLExtras.h" 
- #include <algorithm> 
- #include <cassert> 
- #include <functional> 
- #include <memory> 
-   
- namespace llvm { 
- namespace PBQP { 
-   
- using PBQPNum = float; 
-   
- /// PBQP Vector class. 
- class Vector { 
-   friend hash_code hash_value(const Vector &); 
-   
- public: 
-   /// Construct a PBQP vector of the given size. 
-   explicit Vector(unsigned Length) 
-     : Length(Length), Data(std::make_unique<PBQPNum []>(Length)) {} 
-   
-   /// Construct a PBQP vector with initializer. 
-   Vector(unsigned Length, PBQPNum InitVal) 
-     : Length(Length), Data(std::make_unique<PBQPNum []>(Length)) { 
-     std::fill(Data.get(), Data.get() + Length, InitVal); 
-   } 
-   
-   /// Copy construct a PBQP vector. 
-   Vector(const Vector &V) 
-     : Length(V.Length), Data(std::make_unique<PBQPNum []>(Length)) { 
-     std::copy(V.Data.get(), V.Data.get() + Length, Data.get()); 
-   } 
-   
-   /// Move construct a PBQP vector. 
-   Vector(Vector &&V) 
-     : Length(V.Length), Data(std::move(V.Data)) { 
-     V.Length = 0; 
-   } 
-   
-   /// Comparison operator. 
-   bool operator==(const Vector &V) const { 
-     assert(Length != 0 && Data && "Invalid vector"); 
-     if (Length != V.Length) 
-       return false; 
-     return std::equal(Data.get(), Data.get() + Length, V.Data.get()); 
-   } 
-   
-   /// Return the length of the vector 
-   unsigned getLength() const { 
-     assert(Length != 0 && Data && "Invalid vector"); 
-     return Length; 
-   } 
-   
-   /// Element access. 
-   PBQPNum& operator[](unsigned Index) { 
-     assert(Length != 0 && Data && "Invalid vector"); 
-     assert(Index < Length && "Vector element access out of bounds."); 
-     return Data[Index]; 
-   } 
-   
-   /// Const element access. 
-   const PBQPNum& operator[](unsigned Index) const { 
-     assert(Length != 0 && Data && "Invalid vector"); 
-     assert(Index < Length && "Vector element access out of bounds."); 
-     return Data[Index]; 
-   } 
-   
-   /// Add another vector to this one. 
-   Vector& operator+=(const Vector &V) { 
-     assert(Length != 0 && Data && "Invalid vector"); 
-     assert(Length == V.Length && "Vector length mismatch."); 
-     std::transform(Data.get(), Data.get() + Length, V.Data.get(), Data.get(), 
-                    std::plus<PBQPNum>()); 
-     return *this; 
-   } 
-   
-   /// Returns the index of the minimum value in this vector 
-   unsigned minIndex() const { 
-     assert(Length != 0 && Data && "Invalid vector"); 
-     return std::min_element(Data.get(), Data.get() + Length) - Data.get(); 
-   } 
-   
- private: 
-   unsigned Length; 
-   std::unique_ptr<PBQPNum []> Data; 
- }; 
-   
- /// Return a hash_value for the given vector. 
- inline hash_code hash_value(const Vector &V) { 
-   unsigned *VBegin = reinterpret_cast<unsigned*>(V.Data.get()); 
-   unsigned *VEnd = reinterpret_cast<unsigned*>(V.Data.get() + V.Length); 
-   return hash_combine(V.Length, hash_combine_range(VBegin, VEnd)); 
- } 
-   
- /// Output a textual representation of the given vector on the given 
- ///        output stream. 
- template <typename OStream> 
- OStream& operator<<(OStream &OS, const Vector &V) { 
-   assert((V.getLength() != 0) && "Zero-length vector badness."); 
-   
-   OS << "[ " << V[0]; 
-   for (unsigned i = 1; i < V.getLength(); ++i) 
-     OS << ", " << V[i]; 
-   OS << " ]"; 
-   
-   return OS; 
- } 
-   
- /// PBQP Matrix class 
- class Matrix { 
- private: 
-   friend hash_code hash_value(const Matrix &); 
-   
- public: 
-   /// Construct a PBQP Matrix with the given dimensions. 
-   Matrix(unsigned Rows, unsigned Cols) : 
-     Rows(Rows), Cols(Cols), Data(std::make_unique<PBQPNum []>(Rows * Cols)) { 
-   } 
-   
-   /// Construct a PBQP Matrix with the given dimensions and initial 
-   /// value. 
-   Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal) 
-     : Rows(Rows), Cols(Cols), 
-       Data(std::make_unique<PBQPNum []>(Rows * Cols)) { 
-     std::fill(Data.get(), Data.get() + (Rows * Cols), InitVal); 
-   } 
-   
-   /// Copy construct a PBQP matrix. 
-   Matrix(const Matrix &M) 
-     : Rows(M.Rows), Cols(M.Cols), 
-       Data(std::make_unique<PBQPNum []>(Rows * Cols)) { 
-     std::copy(M.Data.get(), M.Data.get() + (Rows * Cols), Data.get()); 
-   } 
-   
-   /// Move construct a PBQP matrix. 
-   Matrix(Matrix &&M) 
-     : Rows(M.Rows), Cols(M.Cols), Data(std::move(M.Data)) { 
-     M.Rows = M.Cols = 0; 
-   } 
-   
-   /// Comparison operator. 
-   bool operator==(const Matrix &M) const { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     if (Rows != M.Rows || Cols != M.Cols) 
-       return false; 
-     return std::equal(Data.get(), Data.get() + (Rows * Cols), M.Data.get()); 
-   } 
-   
-   /// Return the number of rows in this matrix. 
-   unsigned getRows() const { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     return Rows; 
-   } 
-   
-   /// Return the number of cols in this matrix. 
-   unsigned getCols() const { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     return Cols; 
-   } 
-   
-   /// Matrix element access. 
-   PBQPNum* operator[](unsigned R) { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     assert(R < Rows && "Row out of bounds."); 
-     return Data.get() + (R * Cols); 
-   } 
-   
-   /// Matrix element access. 
-   const PBQPNum* operator[](unsigned R) const { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     assert(R < Rows && "Row out of bounds."); 
-     return Data.get() + (R * Cols); 
-   } 
-   
-   /// Returns the given row as a vector. 
-   Vector getRowAsVector(unsigned R) const { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     Vector V(Cols); 
-     for (unsigned C = 0; C < Cols; ++C) 
-       V[C] = (*this)[R][C]; 
-     return V; 
-   } 
-   
-   /// Returns the given column as a vector. 
-   Vector getColAsVector(unsigned C) const { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     Vector V(Rows); 
-     for (unsigned R = 0; R < Rows; ++R) 
-       V[R] = (*this)[R][C]; 
-     return V; 
-   } 
-   
-   /// Matrix transpose. 
-   Matrix transpose() const { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     Matrix M(Cols, Rows); 
-     for (unsigned r = 0; r < Rows; ++r) 
-       for (unsigned c = 0; c < Cols; ++c) 
-         M[c][r] = (*this)[r][c]; 
-     return M; 
-   } 
-   
-   /// Add the given matrix to this one. 
-   Matrix& operator+=(const Matrix &M) { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     assert(Rows == M.Rows && Cols == M.Cols && 
-            "Matrix dimensions mismatch."); 
-     std::transform(Data.get(), Data.get() + (Rows * Cols), M.Data.get(), 
-                    Data.get(), std::plus<PBQPNum>()); 
-     return *this; 
-   } 
-   
-   Matrix operator+(const Matrix &M) { 
-     assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); 
-     Matrix Tmp(*this); 
-     Tmp += M; 
-     return Tmp; 
-   } 
-   
- private: 
-   unsigned Rows, Cols; 
-   std::unique_ptr<PBQPNum []> Data; 
- }; 
-   
- /// Return a hash_code for the given matrix. 
- inline hash_code hash_value(const Matrix &M) { 
-   unsigned *MBegin = reinterpret_cast<unsigned*>(M.Data.get()); 
-   unsigned *MEnd = 
-     reinterpret_cast<unsigned*>(M.Data.get() + (M.Rows * M.Cols)); 
-   return hash_combine(M.Rows, M.Cols, hash_combine_range(MBegin, MEnd)); 
- } 
-   
- /// Output a textual representation of the given matrix on the given 
- ///        output stream. 
- template <typename OStream> 
- OStream& operator<<(OStream &OS, const Matrix &M) { 
-   assert((M.getRows() != 0) && "Zero-row matrix badness."); 
-   for (unsigned i = 0; i < M.getRows(); ++i) 
-     OS << M.getRowAsVector(i) << "\n"; 
-   return OS; 
- } 
-   
- template <typename Metadata> 
- class MDVector : public Vector { 
- public: 
-   MDVector(const Vector &v) : Vector(v), md(*this) {} 
-   MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { } 
-   
-   const Metadata& getMetadata() const { return md; } 
-   
- private: 
-   Metadata md; 
- }; 
-   
- template <typename Metadata> 
- inline hash_code hash_value(const MDVector<Metadata> &V) { 
-   return hash_value(static_cast<const Vector&>(V)); 
- } 
-   
- template <typename Metadata> 
- class MDMatrix : public Matrix { 
- public: 
-   MDMatrix(const Matrix &m) : Matrix(m), md(*this) {} 
-   MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { } 
-   
-   const Metadata& getMetadata() const { return md; } 
-   
- private: 
-   Metadata md; 
- }; 
-   
- template <typename Metadata> 
- inline hash_code hash_value(const MDMatrix<Metadata> &M) { 
-   return hash_value(static_cast<const Matrix&>(M)); 
- } 
-   
- } // end namespace PBQP 
- } // end namespace llvm 
-   
- #endif // LLVM_CODEGEN_PBQP_MATH_H 
-