@@ -131,23 +131,137 @@ def Polynomial_PolynomialType : Polynomial_Type<"Polynomial", "polynomial"> {
131
131
let assemblyFormat = "`<` $ring `>`";
132
132
}
133
133
134
+ def PolynomialLike: TypeOrContainer<Polynomial_PolynomialType, "polynomial-like">;
135
+
134
136
class 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
+ }
136
142
137
143
class Polynomial_UnaryOp<string mnemonic, list<Trait> traits = []> :
138
144
Polynomial_Op<mnemonic, traits # [SameOperandsAndResultType]> {
139
145
let arguments = (ins Polynomial_PolynomialType:$operand);
140
146
let results = (outs Polynomial_PolynomialType:$result);
141
-
142
- let assemblyFormat = "$operand attr-dict `:` qualified(type($result))";
143
147
}
144
148
145
149
class 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
+ }
149
259
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))";
151
265
}
152
266
153
267
#endif // POLYNOMIAL_OPS
0 commit comments