@@ -22,12 +22,22 @@ class CheddarGPU_Op<string mnemonic, list<Trait> traits = []>
2222 }];
2323}
2424
25+ defvar CheddarGPU_UnaryForms = (ins
26+ CheddarGPU_FormAttr:$in_form,
27+ CheddarGPU_FormAttr:$out_form
28+ );
29+
2530defvar CheddarGPU_BinaryForms = (ins
2631 CheddarGPU_FormAttr:$lhs_form,
2732 CheddarGPU_FormAttr:$rhs_form,
2833 CheddarGPU_FormAttr:$out_form
2934);
3035
36+ defvar CheddarGPU_UnaryLimbRanges = (ins
37+ OptionalAttr<CheddarGPU_LimbRangeAttr>:$in_limb_range,
38+ OptionalAttr<CheddarGPU_LimbRangeAttr>:$out_limb_range
39+ );
40+
3141defvar CheddarGPU_BinaryLimbRanges = (ins
3242 OptionalAttr<CheddarGPU_LimbRangeAttr>:$lhs_limb_range,
3343 OptionalAttr<CheddarGPU_LimbRangeAttr>:$rhs_limb_range,
@@ -61,6 +71,27 @@ defvar CheddarGPU_BinaryBuilders = [
6171 }]>
6272];
6373
74+ defvar CheddarGPU_UnaryBuilders = [
75+ OpBuilder<(ins "::mlir::Value":$out,
76+ "::mlir::Value":$in,
77+ "::mlir::heir::cheddar_gpu::FormAttr":$in_form,
78+ "::mlir::heir::cheddar_gpu::FormAttr":$out_form,
79+ CArg<"::mlir::DenseI64ArrayAttr", "{}">:$in_limb_range,
80+ CArg<"::mlir::DenseI64ArrayAttr", "{}">:$out_limb_range), [{
81+ build($_builder, $_state, out, in, in_form, out_form,
82+ in_limb_range, out_limb_range, /*num_aux=*/::mlir::IntegerAttr{});
83+ }]>,
84+ OpBuilder<(ins "::mlir::Value":$out,
85+ "::mlir::Value":$in,
86+ "::mlir::heir::cheddar_gpu::Form":$in_form,
87+ "::mlir::heir::cheddar_gpu::Form":$out_form,
88+ CArg<"::mlir::DenseI64ArrayAttr", "{}">:$in_limb_range,
89+ CArg<"::mlir::DenseI64ArrayAttr", "{}">:$out_limb_range), [{
90+ build($_builder, $_state, out, in, in_form, out_form,
91+ in_limb_range, out_limb_range, /*num_aux=*/::mlir::IntegerAttr{});
92+ }]>
93+ ];
94+
6495//===----------------------------------------------------------------------===//
6596// Operation Families
6697//===----------------------------------------------------------------------===//
@@ -89,6 +120,30 @@ class CheddarGPU_BinaryOpBase<string mnemonic, list<Trait> traits = []>
89120 }];
90121}
91122
123+ // Unary element-wise operations on single polynomial buffers (neg).
124+ class CheddarGPU_UnaryOpBase<string mnemonic, dag extraAttrs = (ins),
125+ list<OpBuilder> opBuilders = [], list<Trait> traits = []>
126+ : CheddarGPU_Op<mnemonic, !listconcat([
127+ AllTypesMatch<["out", "in"]>,
128+ CheddarGPU_LimbRangesWithin
129+ ], traits)> {
130+ let arguments = !con(
131+ (ins
132+ Arg<CheddarGPU_PolyBuffer, "destination buffer", [MemWrite]>:$out,
133+ Arg<CheddarGPU_PolyBuffer, "input polynomial buffer", [MemRead]>:$in
134+ ),
135+ CheddarGPU_UnaryForms,
136+ extraAttrs,
137+ CheddarGPU_UnaryLimbRanges,
138+ (ins OptionalAttr<CheddarGPU_NonNegI64Attr>:$num_aux)
139+ );
140+
141+ let builders = opBuilders;
142+ let assemblyFormat = [{
143+ $out `,` $in prop-dict attr-dict `:` type($out)
144+ }];
145+ }
146+
92147//===----------------------------------------------------------------------===//
93148// Binary and Unary Element-Wise Operations
94149//===----------------------------------------------------------------------===//
@@ -121,6 +176,20 @@ def CheddarGPU_SubOp : CheddarGPU_BinaryOpBase<"sub", [
121176 }];
122177}
123178
179+ def CheddarGPU_NegOp : CheddarGPU_UnaryOpBase<"neg", (ins), CheddarGPU_UnaryBuilders, [
180+ CheddarGPU_FormsMatch<["in_form", "out_form"]>]> {
181+ let summary = "Pointwise modular negation of a polynomial buffer";
182+ let description = [{
183+ Mirrors Cheddar's `kernel::Neg` and `ElementWiseHandler::Neg` in `ElementWise.cu`.
184+ Computes `out = -in mod Q` limb-wise, where the limbs of `Q` are defined
185+ in `CheddarGPU_ParamsAttr`.
186+
187+ Form contract:
188+ - Valid in both `coeff` and `eval` domain.
189+ - Preserves representation form (`in_form == out_form`).
190+ }];
191+ }
192+
124193def CheddarGPU_MulOp : CheddarGPU_BinaryOpBase<"mul", [
125194 CheddarGPU_FormsAre<["lhs_form", "rhs_form", "out_form"], CheddarGPU_Form_Eval>]> {
126195 let summary = "Pointwise Montgomery modular multiplication";
0 commit comments