Utility function for adding a generic quantum operation to the MLIR representation for the PyKernel. A controlled version can be invoked by passing additional arguments to the operation. For an N-qubit operation, the last N arguments are treated as `targets` and excess argument
(self, opName, *args)
| 177 | |
| 178 | |
| 179 | def __generalCustomOperation(self, opName, *args): |
| 180 | """ |
| 181 | Utility function for adding a generic quantum operation to the MLIR |
| 182 | representation for the PyKernel. |
| 183 | |
| 184 | A controlled version can be invoked by passing additional arguments to the |
| 185 | operation. For an N-qubit operation, the last N arguments are treated as |
| 186 | `targets` and excess arguments as `controls`. |
| 187 | """ |
| 188 | |
| 189 | global globalRegisteredOperations |
| 190 | unitary = globalRegisteredOperations[opName] |
| 191 | |
| 192 | numTargets = int(np.log2(np.sqrt(unitary.size))) |
| 193 | |
| 194 | qubits = [] |
| 195 | self.clearCache() |
| 196 | with self.insertPoint, self.loc: |
| 197 | for arg in args: |
| 198 | if isinstance(arg, QuakeValue): |
| 199 | qubits.append(arg.mlirValue) |
| 200 | else: |
| 201 | emitFatalError(f"invalid argument type passed to {opName}.") |
| 202 | |
| 203 | targets = [] |
| 204 | controls = [] |
| 205 | |
| 206 | if numTargets == len(qubits): |
| 207 | targets = qubits |
| 208 | elif numTargets < len(qubits): |
| 209 | numControls = len(qubits) - numTargets |
| 210 | targets = qubits[-numTargets:] |
| 211 | controls = qubits[:numControls] |
| 212 | else: |
| 213 | emitFatalError( |
| 214 | f"too few arguments passed to {opName}, expected ({numTargets})" |
| 215 | ) |
| 216 | |
| 217 | globalName = f'{nvqppPrefix}{opName}_generator_{numTargets}.rodata' |
| 218 | currentST = SymbolTable(self.module.operation) |
| 219 | if not globalName in currentST: |
| 220 | with InsertionPoint(self.module.body): |
| 221 | gen_vector_of_complex_constant(self.loc, self.module, |
| 222 | globalName, unitary.tolist()) |
| 223 | |
| 224 | quake.CustomUnitaryConstantOp([], |
| 225 | matrix=FlatSymbolRefAttr.get(globalName), |
| 226 | parameters=[], |
| 227 | controls=controls, |
| 228 | targets=targets, |
| 229 | is_adj=False) |
| 230 | return |
| 231 | |
| 232 | |
| 233 | class PyKernel(object): |
nothing calls this directly
no test coverage detected