@@ -131,23 +131,137 @@ def Polynomial_PolynomialType : Polynomial_Type<"Polynomial", "polynomial"> {
131131 let assemblyFormat = "`<` $ring `>`";
132132}
133133
134+ def PolynomialLike: TypeOrContainer<Polynomial_PolynomialType, "polynomial-like">;
135+
134136class Polynomial_Op<string mnemonic, list<Trait> traits = []> :
135- Op<Polynomial_Dialect, mnemonic, traits # [Pure]>;
137+ Op<Polynomial_Dialect, mnemonic, traits # [Pure]> {
138+ let assemblyFormat = [{
139+ operands attr-dict `:` `(` qualified(type(operands)) `)` `->` qualified(type(results))
140+ }];
141+ }
136142
137143class Polynomial_UnaryOp<string mnemonic, list<Trait> traits = []> :
138144 Polynomial_Op<mnemonic, traits # [SameOperandsAndResultType]> {
139145 let arguments = (ins Polynomial_PolynomialType:$operand);
140146 let results = (outs Polynomial_PolynomialType:$result);
141-
142- let assemblyFormat = "$operand attr-dict `:` qualified(type($result))";
143147}
144148
145149class Polynomial_BinaryOp<string mnemonic, list<Trait> traits = []> :
146- Polynomial_Op<mnemonic, traits # [SameOperandsAndResultType]> {
147- let arguments = (ins Polynomial_PolynomialType:$lhs, Polynomial_PolynomialType:$rhs);
148- let results = (outs Polynomial_PolynomialType:$result);
150+ Polynomial_Op<mnemonic, !listconcat(traits, [Pure, SameOperandsAndResultType, ElementwiseMappable])> {
151+ let arguments = (ins PolynomialLike:$lhs, PolynomialLike:$rhs);
152+ let results = (outs PolynomialLike:$result);
153+ let assemblyFormat = "operands attr-dict `:` qualified(type($result))";
154+ }
155+
156+ def Polynomial_AddOp : Polynomial_BinaryOp<"add", [Commutative]> {
157+ let summary = "Addition operation between polynomials.";
158+ }
159+
160+ def Polynomial_SubOp : Polynomial_BinaryOp<"sub"> {
161+ let summary = "Subtraction operation between polynomials.";
162+ }
163+
164+ def Polynomial_MulOp : Polynomial_BinaryOp<"mul", [Commutative]> {
165+ let summary = "Multiplication operation between polynomials.";
166+ }
167+
168+ def Polynomial_MulScalarOp : Polynomial_Op<"mul_scalar", [
169+ ElementwiseMappable, AllTypesMatch<["polynomial", "output"]>]> {
170+ let summary = "Multiplication by a scalar of the field.";
171+
172+ let arguments = (ins
173+ PolynomialLike:$polynomial,
174+ AnyInteger:$scalar
175+ );
176+
177+ let results = (outs
178+ PolynomialLike:$output
179+ );
180+
181+ let assemblyFormat = "operands attr-dict `:` qualified(type($polynomial)) `,` type($scalar)";
182+ }
183+
184+ def Polynomial_LeadingTermOp: Polynomial_Op<"leading_term"> {
185+ let summary = "Compute the leading term of the polynomial.";
186+ let description = [{
187+ The degree of a polynomial is the largest $k$ for which the coefficient
188+ $a_k$ of $x^k$ is nonzero. The leading term is the term $a_k x^k$, which
189+ this op represents as a pair of results.
190+ }];
191+ let arguments = (ins Polynomial_PolynomialType:$input);
192+ let results = (outs Index:$degree, AnyInteger:$coefficient);
193+ let assemblyFormat = "operands attr-dict `:` qualified(type($input)) `->` `(` type($degree) `,` type($coefficient) `)`";
194+ }
195+
196+ def Polynomial_MonomialOp: Polynomial_Op<"monomial"> {
197+ let summary = "Create a polynomial that consists of a single monomial.";
198+ let arguments = (ins AnyInteger:$coefficient, Index:$degree);
199+ let results = (outs Polynomial_PolynomialType:$output);
200+ }
201+
202+ def Polynomial_MonomialMulOp: Polynomial_Op<"monomial_mul", [AllTypesMatch<["input", "output"]>]> {
203+ let summary = "Multiply a polynomial by a monic monomial.";
204+ let description = [{
205+ In the ring of polynomials mod $x^n - 1$, `monomial_mul` can be interpreted
206+ as a cyclic shift of the coefficients of the polynomial. For some rings,
207+ this results in optimized lowerings that involve rotations and rescaling
208+ of the coefficients of the input.
209+ }];
210+ let arguments = (ins Polynomial_PolynomialType:$input, Index:$monomialDegree);
211+ let results = (outs Polynomial_PolynomialType:$output);
212+ let hasVerifier = 1;
213+ }
214+
215+ def Polynomial_FromTensorOp : Polynomial_Op<"from_tensor", [Pure]> {
216+ let summary = "Creates a polynomial from integer coefficients stored in a tensor.";
217+ let description = [{
218+ `polynomial.from_tensor` creates a polynomial value from a tensor of coefficients.
219+ The input tensor must list the coefficients in degree-increasing order.
220+
221+ The input one-dimensional tensor may have size at most the degree of the
222+ ring's ideal generator polynomial, with smaller dimension implying that
223+ all higher-degree terms have coefficient zero.
224+ }];
225+ let arguments = (ins RankedTensorOf<[AnyInteger]>:$input);
226+ let results = (outs Polynomial_PolynomialType:$output);
227+
228+ let assemblyFormat = "$input attr-dict `:` type($input) `->` qualified(type($output))";
229+
230+ let builders = [
231+ // Builder that infers coefficient modulus from tensor bit width,
232+ // and uses whatever input ring is provided by the caller.
233+ OpBuilder<(ins "::mlir::Value":$input, "RingAttr":$ring)>
234+ ];
235+ let hasVerifier = 1;
236+ }
237+
238+ def Polynomial_ToTensorOp : Polynomial_Op<"to_tensor", [Pure]> {
239+ let summary = "Creates a tensor containing the coefficients of a polynomial.";
240+ let description = [{
241+ `polynomial.to_tensor` creates a tensor value containing the coefficients of the
242+ input polynomial. The output tensor contains the coefficients in
243+ degree-increasing order.
244+
245+ Operations that act on the coefficients of a polynomial, such as extracting
246+ a specific coefficient or extracting a range of coefficients, should be
247+ implemented by composing `to_tensor` with the relevant `tensor` dialect
248+ ops.
249+
250+ The output tensor has shape equal to the degree of the ring's ideal
251+ generator polynomial, including zeroes.
252+ }];
253+ let arguments = (ins Polynomial_PolynomialType:$input);
254+ let results = (outs RankedTensorOf<[AnyInteger]>:$output);
255+ let assemblyFormat = "$input attr-dict `:` qualified(type($input)) `->` type($output)";
256+
257+ let hasVerifier = 1;
258+ }
149259
150- let assemblyFormat = "$lhs `,` $rhs attr-dict `:` qualified(type($result))";
260+ def Polynomial_ConstantOp : Polynomial_Op<"constant", [Pure]> {
261+ let summary = "Define a constant polynomial via an attribute.";
262+ let arguments = (ins Polynomial_PolynomialAttr:$input);
263+ let results = (outs Polynomial_PolynomialType:$output);
264+ let assemblyFormat = "$input attr-dict `:` qualified(type($output))";
151265}
152266
153267#endif // POLYNOMIAL_OPS
0 commit comments