Esempio n. 1
0
 def __init__(self, config: Munch, metagraph: Metagraph):
     super().__init__()
     self._config = config
     self._metagraph = metagraph
     self.__keypair = config.neuron.keypair
     self._remotes = {}
     self.stats = SimpleNamespace(qps=stat_utils.timed_rolling_avg(
         0.0, 0.01), )
Esempio n. 2
0
 def update_stats_for_request(self, request, response):
     self.stats.qps.update(1)
     in_bytes = sys.getsizeof(request)
     out_bytes = sys.getsizeof(response)
     self.stats.total_in_bytes.update(in_bytes)
     self.stats.total_out_bytes.update(out_bytes)
     if request.public_key in self.metagraph.state.uid_for_pubkey:
         # ---- Check we have a stats column for this peer
         request_uid = self.metagraph.state.uid_for_pubkey[request.public_key]
         if request_uid in self.stats.in_bytes_per_uid:
             self.stats.in_bytes_per_uid[request_uid].update(in_bytes)
             self.stats.out_bytes_per_uid[request_uid].update(out_bytes)
             self.stats.qps_per_uid[request_uid].update(1)
         else:
             self.stats.in_bytes_per_uid[request_uid] = stat_utils.timed_rolling_avg(in_bytes, 0.01)
             self.stats.out_bytes_per_uid[request_uid] = stat_utils.timed_rolling_avg(out_bytes, 0.01)
             self.stats.qps_per_uid[request_uid] = stat_utils.timed_rolling_avg(1, 0.01)
Esempio n. 3
0
    def __init__(self, config: Munch, nucleus: Nucleus, metagraph: Metagraph):
        r""" Initializes a new Axon endpoint with passed config and keypair.
            Args:
                config (:obj:`Munch`, `required`): 
                    bittensor Munch config.
                nucleus (:obj:`bittensor.nucleus.Nucleus`, `required`):
                    backend processing nucleus.
                metagraph (:obj:`bittensor.nucleus.Metagraph`, `required`):
                    bittensor network metagraph.
        """
        self._config = config
        self._metagraph = metagraph
        self.__keypair = config.neuron.keypair
        self._nucleus = nucleus

        # Init server objects.
        self._server = grpc.server(
            futures.ThreadPoolExecutor(
                max_workers=self._config.axon.max_workers))
        bittensor_grpc.add_BittensorServicer_to_server(self, self._server)
        self._server.add_insecure_port('[::]:' +
                                       str(self._config.axon.local_port))

        # Local synapse to serve.
        self.synapse = None
        self.priority = {}
        self._next_unknown_priority_increment = 0

        # Gradient queue
        self.gradients = queue.PriorityQueue(
            maxsize=self._config.axon.max_gradients)

        # Serving thread.
        self._thread = None

        # Stats.
        self.stats = SimpleNamespace(
            qps=stat_utils.timed_rolling_avg(0.0, 0.01),
            total_in_bytes=stat_utils.timed_rolling_avg(0.0, 0.01),
            total_out_bytes=stat_utils.timed_rolling_avg(0.0, 0.01),
            in_bytes_per_uid={},
            out_bytes_per_uid={},
            qps_per_uid={},
        )
Esempio n. 4
0
 def update_stats_for_request(self, request, response):
     self.stats.qps.update(1)
     in_bytes = sys.getsizeof(request)
     out_bytes = sys.getsizeof(response)
     self.stats.total_in_bytes.update(in_bytes)
     self.stats.total_out_bytes.update(out_bytes)
     if request.public_key in self.stats.in_bytes_per_pubkey:
         self.stats.in_bytes_per_pubkey[request.public_key].update(in_bytes)
         self.stats.out_bytes_per_pubkey[request.public_key].update(
             out_bytes)
         self.stats.qps_per_pubkey[request.public_key].update(1)
     else:
         self.stats.in_bytes_per_pubkey[
             request.public_key] = stat_utils.timed_rolling_avg(
                 in_bytes, 0.01)
         self.stats.out_bytes_per_pubkey[
             request.public_key] = stat_utils.timed_rolling_avg(
                 out_bytes, 0.01)
         self.stats.qps_per_pubkey[
             request.public_key] = stat_utils.timed_rolling_avg(1, 0.01)
Esempio n. 5
0
 def __init__(self, neuron: bittensor_pb2.Neuron, config, keypair):
     super().__init__()
     self.neuron = neuron  # Endpoint information.
     self.config = config  # Configuration i.e. rpc timeout.
     self.keypair = keypair  # Cryptographic keypair.
     self.signature = None  # Call signature.
     self.nounce = None  # Call nounce.
     self.backoff = 0  # Number o queries to backoff.
     self.next_backoff = 1  # Next backoff level.
     self.stats = SimpleNamespace(
         forward_qps=stat_utils.timed_rolling_avg(0.0, 0.01),
         backward_qps=stat_utils.timed_rolling_avg(0.0, 0.01),
         forward_elapsed_time=stat_utils.timed_rolling_avg(0.0, 0.01),
         forward_bytes_out=stat_utils.timed_rolling_avg(0.0, 0.01),
         forward_bytes_in=stat_utils.timed_rolling_avg(0.0, 0.01),
         backward_bytes_out=stat_utils.timed_rolling_avg(0.0, 0.01),
         backward_bytes_in=stat_utils.timed_rolling_avg(0.0, 0.01),
         codes={
             bittensor_pb2.ReturnCode.Success: 0,
             bittensor_pb2.ReturnCode.Timeout: 0,
             bittensor_pb2.ReturnCode.Backoff: 0,
             bittensor_pb2.ReturnCode.Unavailable: 0,
             bittensor_pb2.ReturnCode.NotImplemented: 0,
             bittensor_pb2.ReturnCode.EmptyRequest: 0,
             bittensor_pb2.ReturnCode.EmptyResponse: 0,
             bittensor_pb2.ReturnCode.InvalidResponse: 0,
             bittensor_pb2.ReturnCode.InvalidRequest: 0,
             bittensor_pb2.ReturnCode.RequestShapeException: 0,
             bittensor_pb2.ReturnCode.ResponseShapeException: 0,
             bittensor_pb2.ReturnCode.RequestSerializationException: 0,
             bittensor_pb2.ReturnCode.ResponseSerializationException: 0,
             bittensor_pb2.ReturnCode.RequestDeserializationException: 0,
             bittensor_pb2.ReturnCode.ResponseDeserializationException: 0,
             bittensor_pb2.ReturnCode.NotServingSynapse: 0,
             bittensor_pb2.ReturnCode.NucleusTimeout: 0,
             bittensor_pb2.ReturnCode.NucleusFull: 0,
             bittensor_pb2.ReturnCode.RequestIncompatibleVersion: 0,
             bittensor_pb2.ReturnCode.ResponseIncompatibleVersion: 0,
             bittensor_pb2.ReturnCode.SenderUnknown: 0,
             bittensor_pb2.ReturnCode.UnknownException: 0,
         })
     # Loop back if the neuron is local.
     if neuron.address == config.axon.external_ip:
         ip = "localhost:"
         if config.axon.external_ip == "host.docker.internal":
             ip = "host.docker.internal:"
         self.endpoint = ip + str(neuron.port)
     else:
         self.endpoint = neuron.address + ':' + str(neuron.port)
     self.channel = grpc.insecure_channel(
         self.endpoint,
         options=[('grpc.max_send_message_length', -1),
                  ('grpc.max_receive_message_length', -1)])
     self.stub = bittensor_grpc.BittensorStub(self.channel)
Esempio n. 6
0
    def __init__(self,
                 config: Munch = None,
                 wallet: 'bittensor.wallet.Wallet' = None,
                 receptor_pass_gradients: bool = None,
                 receptor_timeout: int = None,
                 receptor_do_backoff: bool = None,
                 receptor_max_backoff: int = None):
        r""" Initializes a new Dendrite entry point.
            Args:
                config (:obj:`Munch`, `optional`): 
                    dendrite.Dendrite.config()
                wallet (:obj:`bittensor.wallet.Wallet`, `optional`):
                    bittensor wallet with hotkey and coldkeypub.
                receptor_pass_gradients (default=True, type=bool)
                    Switch to true if the neuron passes gradients to downstream peers.
                        By default the backward call i.e. loss.backward() triggers passing gradients on the wire.
                receptor_timeout (default=0.5, type=float):
                    The per request RPC timeout. a.k.a the maximum request time.
                receptor_do_backoff (default=True, type=bool)
                    Neurons who return non successful return codes are
                        periodically not called with a multiplicative backoff.
                        The backoff doubles until max_backoff and then halves on ever sequential successful request.
                receptor_max_backoff (default=100, type=int)
                    The backoff doubles until this saturation point.
        """
        super().__init__()
        # Config: Holds all config items for this items and those that are recursively defined. Specifically
        # config for you wallet and metagraph.
        if config == None:
            config = Dendrite.default_config()
        config.receptor.pass_gradients = receptor_pass_gradients if receptor_pass_gradients != None else config.receptor.pass_gradients
        config.receptor.timeout = receptor_timeout if receptor_timeout != None else config.receptor.timeout
        config.receptor.do_backoff = receptor_do_backoff if receptor_do_backoff != None else config.receptor.do_backoff
        config.receptor.max_backoff = receptor_max_backoff if receptor_max_backoff != None else config.receptor.max_backoff
        Dendrite.check_config(config)
        self.config = copy.deepcopy(config)

        # Wallet: Holds you hotkey keypair and coldkey pub, which can be used to sign messages
        # and subscribe to the chain.
        if wallet == None:
            wallet = bittensor.wallet.Wallet(self.config)
        self.wallet = wallet

        # Receptors: Holds a set map of publickey -> receptor objects. Receptors encapsulate a TCP connection between
        # this dendrite and an upstream neuron (i.e. a peer we call for representations)
        self._receptors = {}

        # Stats: hold statistics for this dendrite.
        self.stats = SimpleNamespace(qps=stat_utils.timed_rolling_avg(
            0.0, 0.01), )
Esempio n. 7
0
    def __init__(self,
                 config: Munch = None,
                 wallet: 'bittensor.wallet.Wallet' = None,
                 metagraph: 'bittensor.metagraph.Metagraph' = None,
                 **kwargs):
        r""" Initializes a new Dendrite entry point.
            Args:
                config (:obj:`Munch`, `optional`): 
                    dendrite.Dendrite.config()
                wallet (:obj:`bittensor.wallet.Wallet`, `optional`):
                    bittensor wallet with hotkey and coldkeypub.
                metagraph (:obj:`bittensor.metagraph.Metagraph`, `optional`):
                    bittensor network metagraph.
        """
        super().__init__()
        # Config: Holds all config items for this items and those that are recursively defined. Specifically
        # config for you wallet and metagraph.
        if config == None:
            config = Dendrite.default_config()
        Dendrite.check_config(config)
        self.config = config

        # Wallet: Holds you hotkey keypair and coldkey pub, which can be used to sign messages
        # and subscribe to the chain.
        if wallet == None:
            wallet = bittensor.wallet.Wallet(self.config)
        self.wallet = wallet

        # Metagraph: Maintains a connection to the subtensor chain and can be queried for the latest state.
        if metagraph == None:
            metagraph = bittensor.metagraph.Metagraph(self.config, self.wallet)
        self.metagraph = metagraph

        # Receptors: Holds a set map of publickey -> receptor objects. Receptors encapsulate a TCP connection between
        # this dendrite and an upstream neuron (i.e. a peer we call for representations)
        self._receptors = {}

        # Stats: hold statistics for this dendrite.
        self.stats = SimpleNamespace(qps=stat_utils.timed_rolling_avg(
            0.0, 0.01), )
Esempio n. 8
0
    def __init__(self,
                 neuron: bittensor.proto.Neuron,
                 config: Munch = None,
                 wallet: 'bittensor.wallet.Wallet' = None,
                 **kwargs):
        r""" Initializes a receptor grpc connection.
            Args:
                neuron (:obj:`bittensor.proto.Neuron`, `required`):
                    neuron endpoint descriptor proto.
                config (:obj:`Munch`, `optional`): 
                    receptor.Receptor.config()
                wallet (:obj:`bittensor.wallet.Wallet`, `optional`):
                    bittensor wallet with hotkey and coldkeypub.
                pass_gradients (default=True, type=bool)
                    Switch to true if the neuron passes gradients to downstream peers.
                        By default the backward call i.e. loss.backward() triggers passing gradients on the wire.
                timeout (default=0.5, type=float):
                    The per request RPC timeout. a.k.a the maximum request time.
                do_backoff (default=True, type=bool)
                    Neurons who return non successful return codes are
                        periodically not called with a multiplicative backoff.
                        The backoff doubles until max_backoff and then halves on ever sequential successful request.
                max_backoff (default=100, type=int)
                    The backoff doubles until this saturation point.
        """
        super().__init__()
        if config == None:
            config = Receptor.default_config()
        bittensor.config.Config.update_with_kwargs(config.receptor, kwargs)
        Receptor.check_config(config)
        self.config = config  # Configuration information.

        if wallet == None:
            wallet = bittensor.wallet.Wallet(self.config)
        self.wallet = wallet  # Keypair information
        self.neuron = neuron  # Endpoint information.
        self.signature = None  # Call signature.
        self.nounce = None  # Call nounce.
        self.backoff = 0  # Number o queries to backoff.
        self.next_backoff = 1  # Next backoff level.
        self.stats = SimpleNamespace(
            forward_qps=stat_utils.timed_rolling_avg(0.0, 0.01),
            backward_qps=stat_utils.timed_rolling_avg(0.0, 0.01),
            forward_elapsed_time=stat_utils.timed_rolling_avg(0.0, 0.01),
            forward_bytes_out=stat_utils.timed_rolling_avg(0.0, 0.01),
            forward_bytes_in=stat_utils.timed_rolling_avg(0.0, 0.01),
            backward_bytes_out=stat_utils.timed_rolling_avg(0.0, 0.01),
            backward_bytes_in=stat_utils.timed_rolling_avg(0.0, 0.01),
            codes={
                bittensor.proto.ReturnCode.Success: 0,
                bittensor.proto.ReturnCode.Timeout: 0,
                bittensor.proto.ReturnCode.Backoff: 0,
                bittensor.proto.ReturnCode.Unavailable: 0,
                bittensor.proto.ReturnCode.NotImplemented: 0,
                bittensor.proto.ReturnCode.EmptyRequest: 0,
                bittensor.proto.ReturnCode.EmptyResponse: 0,
                bittensor.proto.ReturnCode.InvalidResponse: 0,
                bittensor.proto.ReturnCode.InvalidRequest: 0,
                bittensor.proto.ReturnCode.RequestShapeException: 0,
                bittensor.proto.ReturnCode.ResponseShapeException: 0,
                bittensor.proto.ReturnCode.RequestSerializationException: 0,
                bittensor.proto.ReturnCode.ResponseSerializationException: 0,
                bittensor.proto.ReturnCode.RequestDeserializationException: 0,
                bittensor.proto.ReturnCode.ResponseDeserializationException: 0,
                bittensor.proto.ReturnCode.NotServingSynapse: 0,
                bittensor.proto.ReturnCode.NucleusTimeout: 0,
                bittensor.proto.ReturnCode.NucleusFull: 0,
                bittensor.proto.ReturnCode.RequestIncompatibleVersion: 0,
                bittensor.proto.ReturnCode.ResponseIncompatibleVersion: 0,
                bittensor.proto.ReturnCode.SenderUnknown: 0,
                bittensor.proto.ReturnCode.UnknownException: 0,
            })
        # Loop back if the neuron is local.
        try:
            external_ip = self.config.axon.external_ip
        except:
            pass
        try:
            external_ip = self.config.axon.external_ip
        except:
            pass
        finally:
            external_ip = None
        if neuron.address == external_ip:
            ip = "localhost:"
            self.endpoint = ip + str(neuron.port)
        else:
            self.endpoint = neuron.address + ':' + str(neuron.port)
        self.channel = grpc.insecure_channel(
            self.endpoint,
            options=[('grpc.max_send_message_length', -1),
                     ('grpc.max_receive_message_length', -1)])
        self.stub = bittensor.grpc.BittensorStub(self.channel)
Esempio n. 9
0
    def __init__(
            self, 
            config: Munch = None, 
            wallet: 'bittensor.wallet.Wallet' = None,
            nucleus: 'bittensor.nucleus.Nucleus' = None,
            metagraph: 'bittensor.metagraph.Metagraph' = None,
            **kwargs
        ):
        r""" Initializes a new Axon tensor processing endpoint.
            
            Args:
                config (:obj:`Munch`, `optional`): 
                    axon.Axon.config()
                wallet (:obj:`bittensor.wallet.Wallet`, `optional`):
                    bittensor wallet with hotkey and coldkeypub.
                nucleus (:obj:`bittensor.nucleus.Nucleus`, `optional`):
                    backend processing nucleus.
                metagraph (:obj:`bittensor.metagraph.Metagraph`, `optional`):
                    bittensor network metagraph.
                local_port (default=8091, type=int): 
                    The port this axon endpoint is served on. i.e. 8091
                local_ip (default='127.0.0.1', type=str): 
                    The local ip this axon binds to. ie. 0.0.0.0
                use_upnpc (default=False, type=bool):
                    If true this axon will attempt to open a port on your router using upnpc.
                external_ip (default=None, type=str):
                    The remote IP served to chain.
                        This ip is subscribed to the chain on boot and is the endpoint other peers see.
                        By default this field is None and is collected by querying a remote server during check_config. 
                        i.e. 207.12.233.1
                external_port (default=None, type=str):
                    The remote port to subscribe on chain. By default this port is the same as local_port.
                        If use_upnpc is true this port is determined after the port mapping
                max_workers (default=10, type=int): 
                    The maximum number connection handler threads working simultaneously on this endpoint. 
                        The grpc server distributes new worker threads to service requests up to this number.
                max_gradients (default=100, type=int):
                    The max number of lingering gradients stored in the gradient queue.
                        Gradients passed from other peers accumulate on this endpoint and queue in axon.gradients.
        """
        # Config: Holds all config items for this items and those that are recursively defined. For instance,
        # config for the wallet, metagraph, and nucleus sub-objects.
        if config == None:
            config = Axon.default_config()
        bittensor.config.Config.update_with_kwargs(config.axon, kwargs) 
        Axon.check_config( config )
        self.config = config

        # Wallet: Holds you hotkey keypair and coldkey pub, which can be used to sign messages 
        # and subscribe to the chain.
        if wallet == None:
            wallet = bittensor.wallet.Wallet( config = self.config )
        self.wallet = wallet
        
        # Metagraph: Maintains a connection to the subtensor chain which updates with a sync() call.
        # The metagraph can be queried for the latest information about stake and weight matrix state.
        if metagraph == None:
            metagraph = bittensor.metagraph.Metagraph( config = self.config, wallet = self.wallet )
        self.metagraph = metagraph

        # Nucleus: Request processing object. The Axon servicer passes requests to this
        # object to perform the actual computation. Can be ripped out and replaced with various
        # computational objects.
        if nucleus == None:
            nucleus = bittensor.nucleus.Nucleus( config = self.config, wallet = self.wallet, metagraph = self.metagraph )
        self.nucleus = nucleus

        # Server: by default the axon serves an RPC server in its own thread using GPRC.
        # The servicer must implement Forward and Backward methods to properly communicate with
        # the other peers in the network.
        self._server = grpc.server(futures.ThreadPoolExecutor(max_workers=self.config.axon.max_workers))
        bittensor.grpc.add_BittensorServicer_to_server(self, self._server)
        self._server.add_insecure_port('[::]:' + str(self.config.axon.local_port))

        # Local Synapse: The synapse object that will be served to the network on this endpoint.
        # Must be set by calling axon.server( synapse_object ). This object is not copied by default 
        # and therefore should be threadsafe when run with any nucleus that alos runs in a separate thread 
        # to the main training thread. 
        self.synapse = None

        # A map between public key and processing priority.
        self.priority = {}

        # Gradient queue: A queue of (input, gradient) tuples.
        self.gradients = queue.PriorityQueue(maxsize = self.config.axon.max_gradients)

        # Serving thread: A thread which runs the axon servicer passing items to the nucleus for
        # further processing.
        self._thread = None

        # Stats: Memory of network statistics, QPS and bytes in and out for instance.
        self.stats = SimpleNamespace(
            qps = stat_utils.timed_rolling_avg(0.0, 0.01),
            total_in_bytes = stat_utils.timed_rolling_avg(0.0, 0.01),
            total_out_bytes= stat_utils.timed_rolling_avg(0.0, 0.01),
            in_bytes_per_uid = {},
            out_bytes_per_uid = {},
            qps_per_uid = {},
        )
Esempio n. 10
0
 def __init__(self,
              neuron: bittensor.proto.Neuron,
              config: Munch = None,
              wallet: 'bittensor.wallet.Wallet' = None):
     r""" Initializes a receptor grpc connection.
         Args:
             neuron (:obj:`bittensor.proto.Neuron`, `required`):
                 neuron endpoint descriptor proto.
             config (:obj:`Munch`, `optional`): 
                 receptor.Receptor.config()
             wallet (:obj:`bittensor.wallet.Wallet`, `optional`):
                 bittensor wallet with hotkey and coldkeypub.
     """
     super().__init__()
     if config == None:
         config = Receptor.build_config()
     self.config = config  # Configuration information.
     if wallet == None:
         wallet = bittensor.wallet.Wallet()
     self.wallet = wallet  # Keypair information
     self.neuron = neuron  # Endpoint information.
     self.signature = None  # Call signature.
     self.nounce = None  # Call nounce.
     self.backoff = 0  # Number o queries to backoff.
     self.next_backoff = 1  # Next backoff level.
     self.stats = SimpleNamespace(
         forward_qps=stat_utils.timed_rolling_avg(0.0, 0.01),
         backward_qps=stat_utils.timed_rolling_avg(0.0, 0.01),
         forward_elapsed_time=stat_utils.timed_rolling_avg(0.0, 0.01),
         forward_bytes_out=stat_utils.timed_rolling_avg(0.0, 0.01),
         forward_bytes_in=stat_utils.timed_rolling_avg(0.0, 0.01),
         backward_bytes_out=stat_utils.timed_rolling_avg(0.0, 0.01),
         backward_bytes_in=stat_utils.timed_rolling_avg(0.0, 0.01),
         codes={
             bittensor.proto.ReturnCode.Success: 0,
             bittensor.proto.ReturnCode.Timeout: 0,
             bittensor.proto.ReturnCode.Backoff: 0,
             bittensor.proto.ReturnCode.Unavailable: 0,
             bittensor.proto.ReturnCode.NotImplemented: 0,
             bittensor.proto.ReturnCode.EmptyRequest: 0,
             bittensor.proto.ReturnCode.EmptyResponse: 0,
             bittensor.proto.ReturnCode.InvalidResponse: 0,
             bittensor.proto.ReturnCode.InvalidRequest: 0,
             bittensor.proto.ReturnCode.RequestShapeException: 0,
             bittensor.proto.ReturnCode.ResponseShapeException: 0,
             bittensor.proto.ReturnCode.RequestSerializationException: 0,
             bittensor.proto.ReturnCode.ResponseSerializationException: 0,
             bittensor.proto.ReturnCode.RequestDeserializationException: 0,
             bittensor.proto.ReturnCode.ResponseDeserializationException: 0,
             bittensor.proto.ReturnCode.NotServingSynapse: 0,
             bittensor.proto.ReturnCode.NucleusTimeout: 0,
             bittensor.proto.ReturnCode.NucleusFull: 0,
             bittensor.proto.ReturnCode.RequestIncompatibleVersion: 0,
             bittensor.proto.ReturnCode.ResponseIncompatibleVersion: 0,
             bittensor.proto.ReturnCode.SenderUnknown: 0,
             bittensor.proto.ReturnCode.UnknownException: 0,
         })
     # Loop back if the neuron is local.
     try:
         external_ip = self.config.axon.external_ip
     except:
         pass
     try:
         external_ip = self.config.axon.external_ip
     except:
         pass
     finally:
         external_ip = None
     if neuron.address == external_ip:
         ip = "localhost:"
         self.endpoint = ip + str(neuron.port)
     else:
         self.endpoint = neuron.address + ':' + str(neuron.port)
     self.channel = grpc.insecure_channel(
         self.endpoint,
         options=[('grpc.max_send_message_length', -1),
                  ('grpc.max_receive_message_length', -1)])
     self.stub = bittensor.grpc.BittensorStub(self.channel)
Esempio n. 11
0
    def __init__(
        self,
        wallet: 'bittensor.wallet',
        endpoint: 'bittensor.Endpoint',
        channel: 'grpc._Channel',
        stub: 'bittensor.grpc.BittensorStub',
    ):
        r""" Initializes a receptor grpc connection.

            Args:
                wallet (:obj:`bittensor.Wallet`, `required`):
                    bittensor wallet with hotkey and coldkeypub.
                endpoint (:obj:`bittensor.Endpoint`, `required`):
                    neuron endpoint descriptor proto.
                channel (:obj:`grpc._Channel`, `required`):
                    grpc TCP channel.
                endpoint (:obj:`bittensor.grpc.BittensorStub`, `required`):
                    bittensor protocol stub created from channel.
        """
        super().__init__()
        self.wallet = wallet  # Keypair information
        self.endpoint = endpoint  # Endpoint information.
        self.channel = channel
        self.stub = stub
        self.backoff = 0  # Number o queries to backoff.
        self.next_backoff = 1  # Next backoff level.
        self.receptor_uid = str(uuid.uuid1())
        self.state_dict = _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY
        self.stats = SimpleNamespace(
            forward_qps=stat_utils.timed_rolling_avg(0.0, 0.01),
            backward_qps=stat_utils.timed_rolling_avg(0.0, 0.01),
            forward_elapsed_time=stat_utils.timed_rolling_avg(0.0, 0.01),
            forward_bytes_out=stat_utils.timed_rolling_avg(0.0, 0.01),
            forward_bytes_in=stat_utils.timed_rolling_avg(0.0, 0.01),
            backward_bytes_out=stat_utils.timed_rolling_avg(0.0, 0.01),
            backward_bytes_in=stat_utils.timed_rolling_avg(0.0, 0.01),
            codes={
                bittensor.proto.ReturnCode.NoReturn: 0,
                bittensor.proto.ReturnCode.Success: 0,
                bittensor.proto.ReturnCode.Timeout: 0,
                bittensor.proto.ReturnCode.Backoff: 0,
                bittensor.proto.ReturnCode.Unavailable: 0,
                bittensor.proto.ReturnCode.NotImplemented: 0,
                bittensor.proto.ReturnCode.EmptyRequest: 0,
                bittensor.proto.ReturnCode.EmptyResponse: 0,
                bittensor.proto.ReturnCode.InvalidResponse: 0,
                bittensor.proto.ReturnCode.InvalidRequest: 0,
                bittensor.proto.ReturnCode.RequestShapeException: 0,
                bittensor.proto.ReturnCode.ResponseShapeException: 0,
                bittensor.proto.ReturnCode.RequestSerializationException: 0,
                bittensor.proto.ReturnCode.ResponseSerializationException: 0,
                bittensor.proto.ReturnCode.RequestDeserializationException: 0,
                bittensor.proto.ReturnCode.ResponseDeserializationException: 0,
                bittensor.proto.ReturnCode.NotServingNucleus: 0,
                bittensor.proto.ReturnCode.NucleusTimeout: 0,
                bittensor.proto.ReturnCode.NucleusFull: 0,
                bittensor.proto.ReturnCode.RequestIncompatibleVersion: 0,
                bittensor.proto.ReturnCode.ResponseIncompatibleVersion: 0,
                bittensor.proto.ReturnCode.SenderUnknown: 0,
                bittensor.proto.ReturnCode.UnknownException: 0,
            })
Esempio n. 12
0
    def __init__(self, config: Munch = None, wallet: 'bittenosr.wallet.Wallet' = None, nucleus: 'bittensor.nucleus.Nucleus' = None, metagraph: 'bittensor.metagraph.Metagraph' = None):
        r""" Initializes a new Axon tensor processing endpoint.
            
            Args:
                config (:obj:`Munch`, `optional`): 
                    axon.Axon.config()
                wallet (:obj:`bittensor.wallet.Wallet`, `optional`):
                    bittensor wallet with hotkey and coldkeypub.
                nucleus (:obj:`bittensor.nucleus.Nucleus`, `optional`):
                    backend processing nucleus.
                metagraph (:obj:`bittensor.metagraph.Metagraph`, `optional`):
                    bittensor network metagraph.
        """
        # Config: Holds all config items for this items and those that are recursively defined. For instance,
        # config for the wallet, metagraph, and nucleus sub-objects.
        if config == None:
            config = Axon.build_config()
        self.config = config

        # Wallet: Holds you hotkey keypair and coldkey pub, which can be used to sign messages 
        # and subscribe to the chain.
        if wallet == None:
            wallet = bittensor.wallet.Wallet( config = self.config )
        self.wallet = wallet
        
        # Metagraph: Maintains a connection to the subtensor chain which updates with a sync() call.
        # The metagraph can be queried for the latest information about stake and weight matrix state.
        if metagraph == None:
            metagraph = bittensor.metagraph.Metagraph( config = self.config, wallet = self.wallet )
        self.metagraph = metagraph

        # Nucleus: Request processing object. The Axon servicer passes requests to this
        # object to perform the actual computation. Can be ripped out and replaced with various
        # computational objects.
        if nucleus == None:
            nucleus = bittensor.nucleus.Nucleus( config = self.config, wallet = self.wallet, metagraph = self.metagraph )
        self.nucleus = nucleus

        # Server: by default the axon serves an RPC server in its own thread using GPRC.
        # The servicer must implement Forward and Backward methods to properly communicate with
        # the other peers in the network.
        self._server = grpc.server(futures.ThreadPoolExecutor(max_workers=self.config.axon.max_workers))
        bittensor.grpc.add_BittensorServicer_to_server(self, self._server)
        self._server.add_insecure_port('[::]:' + str(self.config.axon.local_port))

        # Local Synapse: The synapse object that will be served to the network on this endpoint.
        # Must be set by calling axon.server( synapse_object ). This object is not copied by default 
        # and therefore should be threadsafe when run with any nucleus that alos runs in a separate thread 
        # to the main training thread. 
        self.synapse = None

        # A map between public key and processing priority.
        self.priority = {}

        # Gradient queue: A queue of (input, gradient) tuples.
        self.gradients = queue.PriorityQueue(maxsize = self.config.axon.max_gradients)

        # Serving thread: A thread which runs the axon servicer passing items to the nucleus for
        # further processing.
        self._thread = None

        # Stats: Memory of network statistics, QPS and bytes in and out for instance.
        self.stats = SimpleNamespace(
            qps = stat_utils.timed_rolling_avg(0.0, 0.01),
            total_in_bytes = stat_utils.timed_rolling_avg(0.0, 0.01),
            total_out_bytes= stat_utils.timed_rolling_avg(0.0, 0.01),
            in_bytes_per_uid = {},
            out_bytes_per_uid = {},
            qps_per_uid = {},
        )