Skip to content

Commit

Permalink
[MLIR] Provide convenience gate builders in tablegen (#1180)
Browse files Browse the repository at this point in the history
**Context:**
There's many scheduled circuit transformation work at the mlir layer,
like merge rotations and control flow related transforms, or even
hardware gateset decomposition, where creating new gates will be
necessary.

However, it came to our realization that currently the way to create a
new gate in mlir (aka a `quantum.custom` operation) is more complicated
than necessary, since all the fields need to be specified, even when the
field values are empty. For example, see
https://github.com/PennyLaneAI/catalyst/pull/1154/files#diff-bc5ebab69d5c90919840a29058595f8718f5e8a150e141f721250b76a0278f44R49

In light of this, we provide [convenience builders
](https://mlir.llvm.org/docs/DefiningDialects/Operations/#builder-methods)
in tablegen.


**Description of the Change:**
Provide convenience gate builders (aka builders for quantum.custom
operations) in tablegen;

**Benefits:**
No need to specify a bunch of unnecessary boilerplate arguments when
creating a new `quantum.custom` operation in a pass.
This can also be greatly beneficial for external contributors.

**Possible Drawbacks:**

**Related GitHub Issues:**

---------

Co-authored-by: Mehrdad Malek <39844030+mehrdad2m@users.noreply.github.com>
  • Loading branch information
paul0403 and mehrdad2m authored Dec 17, 2024
1 parent 94b0bd6 commit fb3ca52
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions mlir/include/Quantum/IR/QuantumOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,74 @@ def CustomOp : UnitaryGate_Op<"custom", [DifferentiableGate, NoMemoryEffect,
Variadic<QubitType>:$out_ctrl_qubits
);

let builders = [
OpBuilder<
// Convenience builder for a gate with parameters and controls
// Note that number of out_qubits = number of in_qubits,
// and number of out_ctrl_qubits = number of in_ctrl_qubits
(ins
"llvm::StringRef":$gate,
"mlir::ValueRange":$in_qubits,
"mlir::ValueRange":$in_ctrl_qubits,
"mlir::ValueRange":$in_ctrl_values,
"mlir::ValueRange":$params,
CArg<"bool", "false">:$adjoint
),[{
CustomOp::build($_builder, $_state,
/*out_qubits=*/ mlir::TypeRange(in_qubits),
/*out_ctrl_qubits=*/ mlir::TypeRange(in_ctrl_qubits),
/*params=*/ params,
/*in_qubits=*/ in_qubits,
/*gate_name=*/ $_builder.getStringAttr(gate),
/*(optional) adjoint=*/ nullptr,
/*in_ctrl_qubits=*/ in_ctrl_qubits,
/*in_ctrl_values=*/ in_ctrl_values
);

if (adjoint){
$_state.addAttribute("adjoint", $_builder.getUnitAttr());
}
}]>,

OpBuilder<
// Convenience builder for a gate with parameters and no controls
(ins
"llvm::StringRef":$gate,
"mlir::ValueRange":$in_qubits,
"mlir::ValueRange":$params,
CArg<"bool", "false">:$adjoint
),[{
CustomOp::build($_builder, $_state,
gate, in_qubits, mlir::ValueRange(), mlir::ValueRange(),
params, adjoint);
}]>,

OpBuilder<
// Convenience builder for a gate with controls and no parameters
(ins
"llvm::StringRef":$gate,
"mlir::ValueRange":$in_qubits,
"mlir::ValueRange":$in_ctrl_qubits,
"mlir::ValueRange":$in_ctrl_values,
CArg<"bool", "false">:$adjoint
),[{
CustomOp::build($_builder, $_state,
gate, in_qubits, in_ctrl_qubits, in_ctrl_values,
mlir::ValueRange(), adjoint);
}]>,

OpBuilder<
// Convenience builder for a gate with no parameters and no controls
(ins
"llvm::StringRef":$gate,
"mlir::ValueRange":$in_qubits,
CArg<"bool", "false">:$adjoint
),[{
CustomOp::build($_builder, $_state,
gate, in_qubits, mlir::ValueRange(), adjoint);
}]>,
];

let assemblyFormat = [{
$gate_name `(` $params `)` $in_qubits attr-dict ( `ctrls` `(` $in_ctrl_qubits^ `)` )? ( `ctrlvals` `(` $in_ctrl_values^ `)` )? `:` type($out_qubits) (`ctrls` type($out_ctrl_qubits)^ )?
}];
Expand Down

0 comments on commit fb3ca52

Please sign in to comment.