-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
748 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_H_ | ||
#define HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_H_ | ||
|
||
#include "include/Dialect/Poly/IR/PolyDialect.h" | ||
#include "include/Dialect/Poly/IR/Polynomial.h" | ||
|
||
#define GET_ATTRDEF_CLASSES | ||
#include "include/Dialect/Poly/IR/PolyAttributes.h.inc" | ||
|
||
#endif // HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#ifndef HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_TD_ | ||
#define HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_TD_ | ||
|
||
include "PolyDialect.td" | ||
|
||
include "mlir/IR/DialectBase.td" | ||
include "mlir/IR/AttrTypeBase.td" | ||
|
||
class Poly_Attr<string name, string attrMnemonic, list<Trait> traits = []> | ||
: AttrDef<Poly_Dialect, name, traits> { | ||
let mnemonic = attrMnemonic; | ||
} | ||
|
||
class Poly_Attr_With_Custom_Format<string name, list<Trait> traits = []> | ||
: AttrDef<Poly_Dialect, name, traits> { | ||
let mnemonic = ?; | ||
} | ||
|
||
def Polynomial_Attr : Poly_Attr<"Polynomial", "polynomial"> { | ||
let summary = "An attribute containing a polynomial."; | ||
let description = [{ | ||
#poly = #poly.poly<x**1024 + 1> | ||
}]; | ||
|
||
let parameters = (ins "Polynomial":$value); | ||
|
||
let builders = [ | ||
AttrBuilderWithInferredContext<(ins "Polynomial":$value), [{ | ||
return $_get(value.getContext(), value); | ||
}]> | ||
]; | ||
let extraClassDeclaration = [{ | ||
using ValueType = Polynomial; | ||
Polynomial getPolynomial() const { return getValue(); } | ||
}]; | ||
|
||
let skipDefaultBuilders = 1; | ||
let hasCustomAssemblyFormat = 1; | ||
} | ||
|
||
def Ring_Attr : Poly_Attr<"Ring", "ring"> { | ||
let summary = "An attribute specifying a ring."; | ||
let description = [{ | ||
An attribute specifying a polynomial quotient ring with integer | ||
coefficients, $\mathbb{Z}/n\mathbb{Z}[x] / (p(x))$. | ||
|
||
`cmod` is the coefficient modulus $n$, and `ideal` is the ring ideal | ||
$(p(x))$. Because all ideals in a single-variable polynomial ring are | ||
principal, the ideal is defined by a single polynomial. | ||
|
||
#ring = #poly.ring<cmod=1234, ideal=#poly.polynomial<x**1024 + 1>> | ||
}]; | ||
|
||
let parameters = (ins "APInt": $cmod, "Polynomial":$ideal); | ||
|
||
let builders = [ | ||
AttrBuilderWithInferredContext<(ins "APInt": $cmod, "Polynomial":$ideal), [{ | ||
return $_get(ideal.getContext(), cmod, ideal); | ||
}]> | ||
]; | ||
let extraClassDeclaration = [{ | ||
Polynomial ideal() const { return getIdeal(); } | ||
APInt coefficientModulus() const { return getCmod(); } | ||
}]; | ||
|
||
let skipDefaultBuilders = 1; | ||
let hasCustomAssemblyFormat = 1; | ||
} | ||
|
||
|
||
#endif // HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_TD_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
#ifndef HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIAL_H_ | ||
#define HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIAL_H_ | ||
|
||
#include "llvm/ADT/APInt.h" | ||
#include "llvm/ADT/DenseMapInfo.h" | ||
#include "llvm/ADT/Hashing.h" | ||
#include "mlir/Support/LLVM.h" | ||
|
||
namespace mlir { | ||
|
||
class MLIRContext; | ||
|
||
namespace heir { | ||
namespace poly { | ||
|
||
constexpr unsigned APINT_BIT_WIDTH = 64; | ||
|
||
namespace detail { | ||
struct PolynomialStorage; | ||
} // namespace detail | ||
|
||
class Monomial { | ||
public: | ||
Monomial(int64_t coeff, uint64_t expo) | ||
: coefficient(APINT_BIT_WIDTH, coeff), exponent(APINT_BIT_WIDTH, expo) {} | ||
|
||
Monomial(APInt coeff, APInt expo) : coefficient(coeff), exponent(expo) {} | ||
|
||
Monomial() : coefficient(APINT_BIT_WIDTH, 0), exponent(APINT_BIT_WIDTH, 0) {} | ||
|
||
bool operator==(Monomial other) const { | ||
return other.coefficient == coefficient && other.exponent == exponent; | ||
} | ||
bool operator!=(Monomial other) const { | ||
return other.coefficient != coefficient || other.exponent != exponent; | ||
} | ||
|
||
/// Monomials are ordered by exponent. | ||
bool operator<(const Monomial &other) const { | ||
return (exponent.ule(other.exponent)); | ||
} | ||
|
||
// Prints polynomial to 'os'. | ||
void print(raw_ostream &os) const; | ||
|
||
friend ::llvm::hash_code hash_value(Monomial arg); | ||
|
||
public: | ||
APInt coefficient; | ||
|
||
// Always unsigned | ||
APInt exponent; | ||
}; | ||
|
||
/// A single-variable polynomial with integer coefficients. Polynomials are | ||
/// immutable and uniqued. | ||
/// | ||
/// Eg: x^1024 + x + 1 | ||
/// | ||
/// The symbols used as the polynomial's indeterminate don't matter, so long as | ||
/// it is used consistently throughout the polynomial. | ||
class Polynomial { | ||
public: | ||
using ImplType = detail::PolynomialStorage; | ||
|
||
constexpr Polynomial() = default; | ||
explicit Polynomial(ImplType *terms) : terms(terms) {} | ||
|
||
static Polynomial fromMonomials(ArrayRef<Monomial> monomials, | ||
MLIRContext *context); | ||
/// Returns a polynomial with coefficients given by `coeffs` | ||
static Polynomial fromCoefficients(ArrayRef<int64_t> coeffs, | ||
MLIRContext *context); | ||
|
||
MLIRContext *getContext() const; | ||
|
||
explicit operator bool() const { return terms != nullptr; } | ||
bool operator==(Polynomial other) const { return other.terms == terms; } | ||
bool operator!=(Polynomial other) const { return !(other.terms == terms); } | ||
|
||
// Prints polynomial to 'os'. | ||
void print(raw_ostream &os) const; | ||
void dump() const; | ||
|
||
ArrayRef<Monomial> getTerms() const; | ||
|
||
unsigned getDegree() const; | ||
|
||
friend ::llvm::hash_code hash_value(Polynomial arg); | ||
|
||
private: | ||
ImplType *terms{nullptr}; | ||
}; | ||
|
||
// Make Polynomial hashable. | ||
inline ::llvm::hash_code hash_value(Polynomial arg) { | ||
return ::llvm::hash_value(arg.terms); | ||
} | ||
|
||
inline ::llvm::hash_code hash_value(Monomial arg) { | ||
return ::llvm::hash_value(arg.coefficient) ^ ::llvm::hash_value(arg.exponent); | ||
} | ||
|
||
inline raw_ostream &operator<<(raw_ostream &os, Polynomial polynomial) { | ||
polynomial.print(os); | ||
return os; | ||
} | ||
|
||
} // namespace poly | ||
} // namespace heir | ||
} // namespace mlir | ||
|
||
namespace llvm { | ||
|
||
// Polynomials hash just like pointers | ||
template <> | ||
struct DenseMapInfo<mlir::heir::poly::Polynomial> { | ||
static mlir::heir::poly::Polynomial getEmptyKey() { | ||
auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey(); | ||
return mlir::heir::poly::Polynomial( | ||
static_cast<mlir::heir::poly::Polynomial::ImplType *>(pointer)); | ||
} | ||
static mlir::heir::poly::Polynomial getTombstoneKey() { | ||
auto *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey(); | ||
return mlir::heir::poly::Polynomial( | ||
static_cast<mlir::heir::poly::Polynomial::ImplType *>(pointer)); | ||
} | ||
static unsigned getHashValue(mlir::heir::poly::Polynomial val) { | ||
return mlir::heir::poly::hash_value(val); | ||
} | ||
static bool isEqual(mlir::heir::poly::Polynomial LHS, | ||
mlir::heir::poly::Polynomial RHS) { | ||
return LHS == RHS; | ||
} | ||
}; | ||
|
||
} // namespace llvm | ||
|
||
#endif // HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIAL_H_ |
Oops, something went wrong.