Skip to content

[mlir][polynomial] split attributes into its own tablegen #92613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mlir/include/mlir/Dialect/Polynomial/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
add_mlir_dialect(Polynomial polynomial)
add_mlir_doc(Polynomial PolynomialDialect Dialects/ -gen-dialect-doc -dialect=polynomial)

set(LLVM_TARGET_DEFINITIONS Polynomial.td)
set(LLVM_TARGET_DEFINITIONS PolynomialAttributes.td)
mlir_tablegen(PolynomialAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=polynomial)
mlir_tablegen(PolynomialAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=polynomial)
add_public_tablegen_target(MLIRPolynomialAttributesIncGen)
153 changes: 2 additions & 151 deletions mlir/include/mlir/Dialect/Polynomial/IR/Polynomial.td
Original file line number Diff line number Diff line change
Expand Up @@ -13,157 +13,8 @@ include "mlir/IR/BuiltinAttributes.td"
include "mlir/IR/OpBase.td"
include "mlir/Interfaces/InferTypeOpInterface.td"
include "mlir/Interfaces/SideEffectInterfaces.td"

def Polynomial_Dialect : Dialect {
let name = "polynomial";
let cppNamespace = "::mlir::polynomial";
let description = [{
The Polynomial dialect defines single-variable polynomial types and
operations.

The simplest use of `polynomial` is to represent mathematical operations in
a polynomial ring `R[x]`, where `R` is another MLIR type like `i32`.

More generally, this dialect supports representing polynomial operations in a
quotient ring `R[X]/(f(x))` for some statically fixed polynomial `f(x)`.
Two polyomials `p(x), q(x)` are considered equal in this ring if they have the
same remainder when dividing by `f(x)`. When a modulus is given, ring operations
are performed with reductions modulo `f(x)` and relative to the coefficient ring
`R`.

Examples:

```mlir
// A constant polynomial in a ring with i32 coefficients and no polynomial modulus
#ring = #polynomial.ring<coefficientType=i32>
%a = polynomial.constant <1 + x**2 - 3x**3> : polynomial.polynomial<#ring>

// A constant polynomial in a ring with i32 coefficients, modulo (x^1024 + 1)
#modulus = #polynomial.int_polynomial<1 + x**1024>
#ring = #polynomial.ring<coefficientType=i32, polynomialModulus=#modulus>
%a = polynomial.constant <1 + x**2 - 3x**3> : polynomial.polynomial<#ring>

// A constant polynomial in a ring with i32 coefficients, with a polynomial
// modulus of (x^1024 + 1) and a coefficient modulus of 17.
#modulus = #polynomial.int_polynomial<1 + x**1024>
#ring = #polynomial.ring<coefficientType=i32, coefficientModulus=17:i32, polynomialModulus=#modulus>
%a = polynomial.constant <1 + x**2 - 3x**3> : polynomial.polynomial<#ring>
```
}];

let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
}

class Polynomial_Attr<string name, string attrMnemonic, list<Trait> traits = []>
: AttrDef<Polynomial_Dialect, name, traits> {
let mnemonic = attrMnemonic;
}

def Polynomial_IntPolynomialAttr : Polynomial_Attr<"IntPolynomial", "int_polynomial"> {
let summary = "An attribute containing a single-variable polynomial with integer coefficients.";
let description = [{
A polynomial attribute represents a single-variable polynomial with integer
coefficients, which is used to define the modulus of a `RingAttr`, as well
as to define constants and perform constant folding for `polynomial` ops.

The polynomial must be expressed as a list of monomial terms, with addition
or subtraction between them. The choice of variable name is arbitrary, but
must be consistent across all the monomials used to define a single
attribute. The order of monomial terms is arbitrary, each monomial degree
must occur at most once.

Example:

```mlir
#poly = #polynomial.int_polynomial<x**1024 + 1>
```
}];
let parameters = (ins "::mlir::polynomial::IntPolynomial":$polynomial);
let hasCustomAssemblyFormat = 1;
}

def Polynomial_FloatPolynomialAttr : Polynomial_Attr<"FloatPolynomial", "float_polynomial"> {
let summary = "An attribute containing a single-variable polynomial with double precision floating point coefficients.";
let description = [{
A polynomial attribute represents a single-variable polynomial with double
precision floating point coefficients.

The polynomial must be expressed as a list of monomial terms, with addition
or subtraction between them. The choice of variable name is arbitrary, but
must be consistent across all the monomials used to define a single
attribute. The order of monomial terms is arbitrary, each monomial degree
must occur at most once.

Example:

```mlir
#poly = #polynomial.float_polynomial<0.5 x**7 + 1.5>
```
}];
let parameters = (ins "FloatPolynomial":$polynomial);
let hasCustomAssemblyFormat = 1;
}

def Polynomial_RingAttr : Polynomial_Attr<"Ring", "ring"> {
let summary = "An attribute specifying a polynomial ring.";
let description = [{
A ring describes the domain in which polynomial arithmetic occurs. The ring
attribute in `polynomial` represents the more specific case of polynomials
with a single indeterminate; whose coefficients can be represented by
another MLIR type (`coefficientType`); and, if the coefficient type is
integral, whose coefficients are taken modulo some statically known modulus
(`coefficientModulus`).

Additionally, a polynomial ring can specify a _polynomialModulus_, which converts
polynomial arithmetic to the analogue of modular integer arithmetic, where
each polynomial is represented as its remainder when dividing by the
modulus. For single-variable polynomials, an "polynomialModulus" is always specificed
via a single polynomial, which we call `polynomialModulus`.

An expressive example is polynomials with i32 coefficients, whose
coefficients are taken modulo `2**32 - 5`, with a polynomial modulus of
`x**1024 - 1`.

```mlir
#poly_mod = #polynomial.int_polynomial<-1 + x**1024>
#ring = #polynomial.ring<coefficientType=i32,
coefficientModulus=4294967291:i32,
polynomialModulus=#poly_mod>

%0 = ... : polynomial.polynomial<#ring>
```

In this case, the value of a polynomial is always "converted" to a
canonical form by applying repeated reductions by setting `x**1024 = 1`
and simplifying.

The coefficient and polynomial modulus parameters are optional, and the
coefficient modulus is only allowed if the coefficient type is integral.
}];

let parameters = (ins
"Type": $coefficientType,
OptionalParameter<"::mlir::IntegerAttr">: $coefficientModulus,
OptionalParameter<"::mlir::polynomial::IntPolynomialAttr">: $polynomialModulus,
OptionalParameter<"::mlir::IntegerAttr">: $primitiveRoot
);
let assemblyFormat = "`<` struct(params) `>`";
let builders = [
AttrBuilderWithInferredContext<
(ins "::mlir::Type":$coefficientTy,
CArg<"::mlir::IntegerAttr", "nullptr"> :$coefficientModulusAttr,
CArg<"::mlir::polynomial::IntPolynomialAttr", "nullptr"> :$polynomialModulusAttr,
CArg<"::mlir::IntegerAttr", "nullptr"> :$primitiveRootAttr), [{
return $_get(
coefficientTy.getContext(),
coefficientTy,
coefficientModulusAttr,
polynomialModulusAttr,
primitiveRootAttr);
}]>,
];
}
include "mlir/Dialect/Polynomial/IR/PolynomialDialect.td"
include "mlir/Dialect/Polynomial/IR/PolynomialAttributes.td"

class Polynomial_Type<string name, string typeMnemonic>
: TypeDef<Polynomial_Dialect, name> {
Expand Down
125 changes: 125 additions & 0 deletions mlir/include/mlir/Dialect/Polynomial/IR/PolynomialAttributes.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//===- PolynomialOps.td - Polynomial dialect ---------------*- tablegen -*-===//
//
// 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 POLYNOMIAL_ATTRIBUTES
#define POLYNOMIAL_ATTRIBUTES

include "mlir/IR/BuiltinAttributes.td"
include "mlir/Dialect/Polynomial/IR/PolynomialDialect.td"

class Polynomial_Attr<string name, string attrMnemonic, list<Trait> traits = []>
: AttrDef<Polynomial_Dialect, name, traits> {
let mnemonic = attrMnemonic;
}

def Polynomial_IntPolynomialAttr : Polynomial_Attr<"IntPolynomial", "int_polynomial"> {
let summary = "An attribute containing a single-variable polynomial with integer coefficients.";
let description = [{
A polynomial attribute represents a single-variable polynomial with integer
coefficients, which is used to define the modulus of a `RingAttr`, as well
as to define constants and perform constant folding for `polynomial` ops.

The polynomial must be expressed as a list of monomial terms, with addition
or subtraction between them. The choice of variable name is arbitrary, but
must be consistent across all the monomials used to define a single
attribute. The order of monomial terms is arbitrary, each monomial degree
must occur at most once.

Example:

```mlir
#poly = #polynomial.int_polynomial<x**1024 + 1>
```
}];
let parameters = (ins "::mlir::polynomial::IntPolynomial":$polynomial);
let hasCustomAssemblyFormat = 1;
}

def Polynomial_FloatPolynomialAttr : Polynomial_Attr<"FloatPolynomial", "float_polynomial"> {
let summary = "An attribute containing a single-variable polynomial with double precision floating point coefficients.";
let description = [{
A polynomial attribute represents a single-variable polynomial with double
precision floating point coefficients.

The polynomial must be expressed as a list of monomial terms, with addition
or subtraction between them. The choice of variable name is arbitrary, but
must be consistent across all the monomials used to define a single
attribute. The order of monomial terms is arbitrary, each monomial degree
must occur at most once.

Example:

```mlir
#poly = #polynomial.float_polynomial<0.5 x**7 + 1.5>
```
}];
let parameters = (ins "FloatPolynomial":$polynomial);
let hasCustomAssemblyFormat = 1;
}

def Polynomial_RingAttr : Polynomial_Attr<"Ring", "ring"> {
let summary = "An attribute specifying a polynomial ring.";
let description = [{
A ring describes the domain in which polynomial arithmetic occurs. The ring
attribute in `polynomial` represents the more specific case of polynomials
with a single indeterminate; whose coefficients can be represented by
another MLIR type (`coefficientType`); and, if the coefficient type is
integral, whose coefficients are taken modulo some statically known modulus
(`coefficientModulus`).

Additionally, a polynomial ring can specify a _polynomialModulus_, which converts
polynomial arithmetic to the analogue of modular integer arithmetic, where
each polynomial is represented as its remainder when dividing by the
modulus. For single-variable polynomials, an "polynomialModulus" is always specificed
via a single polynomial, which we call `polynomialModulus`.

An expressive example is polynomials with i32 coefficients, whose
coefficients are taken modulo `2**32 - 5`, with a polynomial modulus of
`x**1024 - 1`.

```mlir
#poly_mod = #polynomial.int_polynomial<-1 + x**1024>
#ring = #polynomial.ring<coefficientType=i32,
coefficientModulus=4294967291:i32,
polynomialModulus=#poly_mod>

%0 = ... : polynomial.polynomial<#ring>
```

In this case, the value of a polynomial is always "converted" to a
canonical form by applying repeated reductions by setting `x**1024 = 1`
and simplifying.

The coefficient and polynomial modulus parameters are optional, and the
coefficient modulus is only allowed if the coefficient type is integral.
}];

let parameters = (ins
"Type": $coefficientType,
OptionalParameter<"::mlir::IntegerAttr">: $coefficientModulus,
OptionalParameter<"::mlir::polynomial::IntPolynomialAttr">: $polynomialModulus,
OptionalParameter<"::mlir::IntegerAttr">: $primitiveRoot
);
let assemblyFormat = "`<` struct(params) `>`";
let builders = [
AttrBuilderWithInferredContext<
(ins "::mlir::Type":$coefficientTy,
CArg<"::mlir::IntegerAttr", "nullptr"> :$coefficientModulusAttr,
CArg<"::mlir::polynomial::IntPolynomialAttr", "nullptr"> :$polynomialModulusAttr,
CArg<"::mlir::IntegerAttr", "nullptr"> :$primitiveRootAttr), [{
return $_get(
coefficientTy.getContext(),
coefficientTy,
coefficientModulusAttr,
polynomialModulusAttr,
primitiveRootAttr);
}]>,
];
}

#endif // POLYNOMIAL_ATTRIBUTES
55 changes: 55 additions & 0 deletions mlir/include/mlir/Dialect/Polynomial/IR/PolynomialDialect.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//===- PolynomialDialect.td - Polynomial dialect base ------*- tablegen -*-===//
//
// 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 POLYNOMIAL_DIALECT
#define POLYNOMIAL_DIALECT

include "mlir/IR/OpBase.td"

def Polynomial_Dialect : Dialect {
let name = "polynomial";
let cppNamespace = "::mlir::polynomial";
let description = [{
The Polynomial dialect defines single-variable polynomial types and
operations.

The simplest use of `polynomial` is to represent mathematical operations in
a polynomial ring `R[x]`, where `R` is another MLIR type like `i32`.

More generally, this dialect supports representing polynomial operations in a
quotient ring `R[X]/(f(x))` for some statically fixed polynomial `f(x)`.
Two polyomials `p(x), q(x)` are considered equal in this ring if they have the
same remainder when dividing by `f(x)`. When a modulus is given, ring operations
are performed with reductions modulo `f(x)` and relative to the coefficient ring
`R`.

Examples:

```mlir
// A constant polynomial in a ring with i32 coefficients and no polynomial modulus
#ring = #polynomial.ring<coefficientType=i32>
%a = polynomial.constant <1 + x**2 - 3x**3> : polynomial.polynomial<#ring>

// A constant polynomial in a ring with i32 coefficients, modulo (x^1024 + 1)
#modulus = #polynomial.int_polynomial<1 + x**1024>
#ring = #polynomial.ring<coefficientType=i32, polynomialModulus=#modulus>
%a = polynomial.constant <1 + x**2 - 3x**3> : polynomial.polynomial<#ring>

// A constant polynomial in a ring with i32 coefficients, with a polynomial
// modulus of (x^1024 + 1) and a coefficient modulus of 17.
#modulus = #polynomial.int_polynomial<1 + x**1024>
#ring = #polynomial.ring<coefficientType=i32, coefficientModulus=17:i32, polynomialModulus=#modulus>
%a = polynomial.constant <1 + x**2 - 3x**3> : polynomial.polynomial<#ring>
```
}];

let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
}

#endif // POLYNOMIAL_OPS
2 changes: 1 addition & 1 deletion utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6737,7 +6737,7 @@ cc_library(

td_library(
name = "PolynomialTdFiles",
srcs = ["include/mlir/Dialect/Polynomial/IR/Polynomial.td"],
srcs = glob(["include/mlir/Dialect/Polynomial/IR/*.td"]),
includes = ["include"],
deps = [
":BuiltinDialectTdFiles",
Expand Down
Loading