Beispiel #1
0
    def flush_factory(self, num_iter, do_sequence=False, block_factory=False):
        """
        Flushes the current pending sequence in a factory. It is performed multiple times
        :param num_iter: The amount of times the current pending sequence is performed
        :return: A list of outcomes/qubits that are produced by the commands
        """
        if len(self._pending_headers) == 0:
            return []

        # Initialize should_notify to False
        should_notify = False

        # Store how many of the headers we send will get a response message from the backend
        response_amount = 0

        # Loop over the pending_headers to determine the total length and set should_notify
        for header in self._pending_headers:

            # Check if the current header is a Command header. It can also be a sub header
            if isinstance(header, CQCCmdHeader):
                # set should_notify to True if at least one of all command headers has notify to True
                should_notify = should_notify or header.notify

                # Remember this header if we expect a return messge
                if self.shouldReturn(header.instr):
                    response_amount += 1

        # Determine the CQC Header type
        if num_iter == 1:
            cqc_type = CQC_TP_COMMAND
        else:
            # Build and insert the Factory header
            cqc_type = CQC_TP_FACTORY
            factory_header = CQCFactoryHeader()
            factory_header.setVals(num_iter, should_notify, block_factory)
            # Insert the factory header at the front
            self._pending_headers.insert(0, factory_header)

        # Insert the cqc header
        self.insert_cqc_header(cqc_type)

        # Send all pending headers
        self.send_pending_headers()

        # Reset _pending_headers to an empty list after all headers are sent
        self.reset_pending_headers()

        # Read out any returned messages from the backend
        res = self._handle_factory_response(num_iter,
                                            response_amount,
                                            should_notify=should_notify)

        # Return information that the backend returned
        return res
Beispiel #2
0
    def __enter__(self):

        # Inside a TP_FACTORY, we don't want CQCType headers before every instruction.
        # Therefore, we set this bool to False
        self._conn._inside_cqc_mix = False

        # Create the CQC Type header, and store it so that we can modify its length at __exit__
        self.type_header = CQCTypeHeader()
        self.type_header.setVals(CQCType.FACTORY, length=0)

        # Build the Factory header
        factory_header = CQCFactoryHeader()
        factory_header.setVals(self._repetition_amount)

        # Pend the headers
        self._conn.pend_header(self.type_header)
        self._conn.pend_header(factory_header)
Beispiel #3
0
    def handle_factory(self, header, data):
        fact_l = CQCFactoryHeader.HDR_LENGTH
        # Get factory header
        if len(data) < header.length:
            logging.debug("CQC %s: Missing header(s) in factory", self.name)
            self.return_messages[header.app_id].append(
                self.create_return_message(header.app_id,
                                           CQC_ERR_UNSUPP,
                                           cqc_version=header.version))
            return False
        fact_header = CQCFactoryHeader(data[:fact_l])
        num_iter = fact_header.num_iter
        # Perform operation multiple times
        succ = True
        should_notify = fact_header.notify
        block_factory = fact_header.block
        logging.debug("CQC %s: Performing factory command with %s iterations",
                      self.name, num_iter)
        if block_factory:
            logging.debug("CQC %s: Acquire lock for factory", self.name)
            self._sequence_lock.acquire()

        for _ in range(num_iter):
            try:
                succ, _ = yield self._process_command(header,
                                                      header.length - fact_l,
                                                      data[fact_l:],
                                                      block_factory)
                if succ is False:
                    return False
            except Exception as err:
                logging.error(
                    "CQC {}: Got the following unexpected error when processing factory: {}"
                    .format(self.name, err))
                self.return_messages[header.app_id].append(
                    self.create_return_message(header.app_id,
                                               CQC_ERR_GENERAL,
                                               cqc_version=header.version))
                return False

        if block_factory:
            logging.debug("CQC %s: Releasing lock for factory", self.name)
            self._sequence_lock.release()

        return succ and should_notify