def publish(self, applyModule=True): """ Generate the circuit data Save to memory for local simulator instead of writing to file Example: env.publish() pprint(env.circuit) :param applyModule: make module running and effecting """ self.program = Program() self.program.sdkVersion = sdkVersion # fill in the head _mergePBList( self.program.head.usingQRegs, sorted(self.Q.registerDict.keys()) ) # all the index of the used q registers are put into usingQRegs _mergePBList( self.program.head.usingCRegs, sorted(self.ClassicRegister) ) # all the index of the used classical registers are put into usingCRegs for name, procedure in self.procedureMap.items(): self._makeProcedure(name, procedure) # fill in the circuit for circuitLine in self.circuit: self.program.body.circuit.append(circuitLine._toPB()) if applyModule: # filter the circuit by Modules for module in self.usedModule: self.program = module(self.program)
def _toPB(self, *qRegsIndex): """ Convert to Protobuf object :param qRegsIndex: Quantum registers list used in creating single circuit object :return: the circuit in Protobuf format. Filled with the name of fixed gates and parameters of quantum registers. """ ret = CircuitLine() if len(qRegsIndex) == 0: # fill in the register list # The circuit object is already in Python env. # Directly generate the circuit in Protobuf format according to member variables. for reg in self.qRegs: ret.qRegs.append(reg.index) else: # Insert the new circuit object in module process. # Generate the Protobuf circuit according to parameters. _mergePBList(ret.qRegs, qRegsIndex) # fill in quantum registers assert len(ret.qRegs) == self.bits # The number of quantum registers in circuit must match to the setting. qRegSet = set(qReg for qReg in ret.qRegs) assert len(ret.qRegs) == len(qRegSet) # Quantum registers of operators in circuit should not be duplicated. ret.fixedGate = FixedGateEnum.Value(self.Gate) # fill in the name of fixed gates return ret
def _makeProcedure(self, name, procedure): pbProcedure = self.program.body.procedureMap[name] if len(procedure.params.paramsDict) == 0: pbProcedure.paramCount = 0 else: pbProcedure.paramCount = max( param for param in procedure.params.paramsDict.keys()) + 1 _mergePBList( pbProcedure.usingQRegs, sorted(procedure.Q.registerDict.keys()) ) # all the index of q regs from sub procedures are storing into usingQRegs for circuitLine in procedure.circuit: pbProcedure.circuit.append(circuitLine._toPB())
def _toPB(self, *qRegsIndex): """ Convert to Protobuf object :param qRegsIndex: the quantum register list used in creating single circuit object """ ret = CircuitLine() if len(qRegsIndex) == 0: # fill in the register list # The circuit object is already in the Python env. # Directly generate the circuit in Protobuf format according to the member variables. for reg in self.qRegs: ret.qRegs.append(reg.index) else: # Insert the new circuit object in the module process. # Generate the Protobuf circuit according to the function parameters. _mergePBList(ret.qRegs, qRegsIndex) ret.barrier = True # fill in the barrier field return ret
def _decompose(self, circuitOut, circuitIn): """ Decompose circuit :param circuitOut: output circuit :param circuitIn: input circuit """ for circuitLine in circuitIn: if circuitLine.HasField('compositeGate') and ( self.params is None or circuitLine.compositeGate in self.params): # insert the decomposed circuit if circuitLine.compositeGate == CompositeGateEnum.RZZ: """ RZZ(xyz)(Q0, Q1) = CX(Q0, Q1) U(xyz)(Q1) CX(Q0, Q1) """ circuitOut.append(CX._toPB(*circuitLine.qRegs)) newCircuitLine = CircuitLine() newCircuitLine.rotationGate = U newCircuitLine.qRegs.append(circuitLine.qRegs[1]) _mergePBList(newCircuitLine.paramValues, circuitLine.paramValues) _mergePBList(newCircuitLine.paramIds, circuitLine.paramIds) circuitOut.append(newCircuitLine) circuitOut.append(CX._toPB(*circuitLine.qRegs)) continue # copy the original circuit circuitOut.append(circuitLine)
def _toPB(self, *qRegsIndex): """ Convert to Protobuf object :param qRegsIndex: the quantum register list used in creating single circuit object :return: the circuit in Protobuf format. Filled with the name of composite gates and parameters of quantum registers. """ ret = CircuitLine() if len(qRegsIndex) == 0: # fill in the register list # The circuit object is already in the Python env. # Directly generate the circuit in Protobuf format according to the member variables. for reg in self.qRegs: ret.qRegs.append(reg.index) else: # Insert the new circuit object in the module process. # Generate the Protobuf circuit according to parameters. _mergePBList(ret.qRegs, qRegsIndex) # fill in quantum registers assert len( ret.qRegs ) == self.bits # The number of quantum registers must conform to the setting. qRegSet = set(qReg for qReg in ret.qRegs) assert len(ret.qRegs) == len( qRegSet ) # The quantum registers of operators in circuit should not be duplicated. ret.compositeGate = CompositeGateEnum.Value( self.Gate) # fill in name of the composite gate _mergePBList(ret.paramValues, self.angles) # fill in rotation angles _mergePBList(ret.paramIds, self.procedureParams) # fill in procedure parameters return ret
def _toPB(self, *qRegsIndex): """ Convert to Protobuf object :param qRegsIndex: the quantum register list used in creating single circuit object :return: Protobuf object """ ret = CircuitLine() if len(qRegsIndex) == 0: # fill in the register list # The circuit object is already in the Python env. # Directly generate the circuit in Protobuf format according to the member variables. for reg in self.qRegs: ret.qRegs.append(reg.index) else: # Insert the new circuit object in the module process. # Generate the Protobuf circuit according to the function parameters. _mergePBList(ret.qRegs, qRegsIndex) paramValues = [] paramIds = [] for param in self.procedureParams: if isinstance(param, (int, float)): paramValues.append(param) paramIds.append(-1) else: paramValues.append(0) paramIds.append(param.index) # ProcedureParamStorage if any(paramValues): _mergePBList(ret.paramValues, paramValues) if any([paramId != -1 for paramId in paramIds]): _mergePBList(ret.paramIds, paramIds) ret.procedureName = self.name return ret