Esempio n. 1
0
    def run(self):
        self.logger.starting_server()
        self.sock.listen(5)
        self.logger.accepting_connections()
        while True:
            sock, _ = self.sock.accept()
            sock = FormatSocket(sock)
            workersetup = WorkerPartner.FromString(sock.recv())
            self.logger.accepted_connection()

            fullkey = (workersetup.job_id, workersetup.state_index_start,
                       workersetup.state_index_end,
                       workersetup.output_index_start,
                       workersetup.output_index_end)
            inputkey = (workersetup.job_id, workersetup.state_index_start,
                        workersetup.state_index_end)
            outputkey = (workersetup.job_id, workersetup.output_index_start,
                         workersetup.output_index_end)

            with self.workerlock:
                if inputkey not in self.inputrange_workers:
                    self.inputrange_workers[inputkey] = []
                if outputkey not in self.outputrange_workers:
                    self.outputrange_workers[outputkey] = []

                self.workers[fullkey] = sock
                self.inputrange_workers[inputkey].append(
                    (sock, workersetup.output_index_start,
                     workersetup.output_index_end))
                self.outputrange_workers[outputkey].append(
                    (sock, workersetup.state_index_start,
                     workersetup.state_index_end))
Esempio n. 2
0
class WorkerRunner(Thread):
    def __init__(self,
                 addr: str = 'localhost',
                 port: int = 1708,
                 bindaddr: str = 'localhost',
                 bindport: int = 0,
                 worker_n: int = 28,
                 logger: WorkerLogger = None):
        super().__init__()

        if logger is None:
            self.logger = PrintLogger()
        else:
            self.logger = logger

        sock = socket.socket()
        sock.connect((addr, port))
        b = sock.recv(1)
        if b != b'\x00':
            sock = ssl.wrap_socket(sock)
        self.socket = FormatSocket(sock)

        self.pool = WorkerPoolServer(bindaddr, bindport, logger=logger)
        self.pool.start()

        workerinfo = HostInformation()
        workerinfo.worker_info.n_qubits = worker_n
        workerinfo.worker_info.address = self.pool.addr
        workerinfo.worker_info.port = self.pool.port

        self.socket.send(workerinfo.SerializeToString())
        self.serverapi = SocketServerBackend(self.socket)
        self.addr = addr
        self.port = port
        self.running = True

    def run(self):

        while self.running:
            self.logger.waiting_for_setup()
            cmd = WorkerCommand.FromString(self.socket.recv())
            if cmd.HasField('setup'):
                setup = cmd.setup
                self.logger.accepted_setup(setup)
                worker = WorkerInstance(self.serverapi,
                                        self.pool,
                                        setup,
                                        logger=self.logger)
                worker.run()
            elif cmd.HasField('close'):
                self.running = False
Esempio n. 3
0
class DistributedBackend(StateType):
    def __init__(self,
                 n,
                 server_host: str = 'localhost',
                 server_port: int = 1708):
        super().__init__(n, None)
        self.control_server_addr = (server_host, server_port)

        sock = socket.socket()
        sock.connect(self.control_server_addr)
        # First byte is whether to use ssl or not, all remaining communication is proto based.
        b = sock.recv(1)
        if b != b'\x00':
            sock = ssl.wrap_socket(sock)
        self.socket = FormatSocket(sock)

        # Introduce yourself.
        host_info = HostInformation()
        host_info.client_info.name = 'backend'
        self.socket.send(host_info.SerializeToString())

    @staticmethod
    def make_state(n: int,
                   index_groups: Sequence[Sequence[int]],
                   feed_list: Sequence[InitialState],
                   statetype: type = numpy.complex128) -> StateType:
        distbackend = DistributedBackend(n)

        setup_message = StateSetup()
        setup_message.n = n
        for index_group, initial_state in zip(index_groups, feed_list):
            pb_state = setup_message.states.add()
            pb_state.indices.CopyFrom(indices_to_pbindices(index_group))

            if type(initial_state) == int:
                pb_state.index = initial_state
            else:
                pb_state.vector.CopyFrom(vec_to_pbvec(initial_state))

        distbackend.socket.send(setup_message.SerializeToString())
        resp = StateHandle.FromString(distbackend.socket.recv())

        if resp.HasField('error_message'):
            raise Exception(resp.error_message)
        else:
            distbackend.state = resp.state_handle
            return distbackend

    def kronselect_dot(self,
                       mats: Mapping[IndexType, MatrixType],
                       input_offset: int = 0,
                       output_offset: int = 0) -> None:
        workerop = WorkerOperation()
        for indices in mats:
            mat = mats[indices]
            matop_to_pbmatop(indices, mat, workerop.kronprod.matrices.add())
        workerop.job_id = self.state

        self.socket.send(workerop.SerializeToString())
        conf = WorkerConfirm.FromString(self.socket.recv())

        if conf.HasField('error_message'):
            self.close()
            raise Exception(conf.error_message)
        elif conf.job_id != self.state:
            self.close()
            raise Exception("Server miscommunication: {} != {}".format(
                self.state, conf.job_id))

    def func_apply(self,
                   reg1_indices: IndexType,
                   reg2_indices: IndexType,
                   func: Callable[[int], int],
                   input_offset: int = 0,
                   output_offset: int = 0) -> None:
        raise NotImplemented(
            "Function application not yet supported in distributed backends.")

    def measure(self,
                indices: Sequence[int],
                measured: Optional[int] = None,
                measured_prob: Optional[float] = None,
                input_offset: int = 0,
                output_offset: int = 0):
        workerop = WorkerOperation()
        workerop.job_id = self.state
        workerop.measure.reduce = False
        indices_to_pbindices(indices, workerop.measure.indices)

        self.socket.send(workerop.SerializeToString())
        conf = WorkerConfirm.FromString(self.socket.recv())

        if conf.HasField('error_message'):
            raise Exception(conf.error_message)
        else:
            return conf.measure_result.measured_bits, conf.measure_result.measured_prob

    def reduce_measure(self,
                       indices: IndexType,
                       measured: Optional[int] = None,
                       measured_prob: Optional[float] = None,
                       input_offset: int = 0,
                       output_offset: int = 0) -> Tuple[int, float]:
        workerop = WorkerOperation()
        workerop.job_id = self.state
        workerop.measure.reduce = True
        indices_to_pbindices(indices, workerop.measure.indices)

        self.socket.send(workerop.SerializeToString())
        conf = WorkerConfirm.FromString(self.socket.recv())

        if conf.HasField('error_message'):
            raise Exception(conf.error_message)
        else:
            return conf.measure_result.measured_bits, conf.measure_result.measured_prob

    def soft_measure(self,
                     indices: Sequence[int],
                     measured: Optional[int] = None,
                     input_offset: int = 0):
        raise NotImplemented(
            "Soft measurement not yet supported in distributed backends.")

    def measure_probabilities(
            self,
            indices: IndexType,
            top_k: int = 0) -> Tuple[Sequence[int], Sequence[float]]:
        if not top_k:
            top_k = pow(2, len(indices))

        workerop = WorkerOperation()
        workerop.job_id = self.state
        workerop.measure.top_k = top_k
        indices_to_pbindices(indices, workerop.measure.indices)

        self.socket.send(workerop.SerializeToString())
        conf = WorkerConfirm.FromString(self.socket.recv())

        if conf.HasField('error_message'):
            raise Exception(conf.error_message)
        else:
            return list(conf.measure_result.top_k_indices.index), list(
                conf.measure_result.top_k_probs)

    def close(self):
        close_op = WorkerOperation()
        close_op.close = True
        self.socket.send(close_op.SerializeToString())
        self.socket.close()