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

Out of tree we have other dialects that use the ring attribute, but we
get compilation errors when generating ops while pulling in all the
Polynomial tablegen ops (there's no `-dialect` flag in `mlir-tblgen` for
op generation like there is for attributes and types).

This PR simply moves the attributes into its own file, so it can be
included separately, and this also requires moving the dialect
declaration into its own file.
This commit is contained in:
Jeremy Kun
2024-05-17 16:03:44 -07:00
committed by GitHub
parent ab7930bd9f
commit b80e0fbcfb
5 changed files with 184 additions and 153 deletions

View File

@@ -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)

View File

@@ -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> {

View File

@@ -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

View File

@@ -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

View File

@@ -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",