예제 #1
0
    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)
예제 #2
0
    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
예제 #3
0
 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())
예제 #4
0
    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
예제 #5
0
    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)
예제 #6
0
    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
예제 #7
0
    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