def _start_manager(self): def get_knowledge_queue(idx): global knowledge_queues if idx < len(knowledge_queues): return knowledge_queues[idx] else: return None def get_s2t_queue(): global s2t_queue return s2t_queue def get_t2s_queue(): global t2s_queue return t2s_queue def get_cmd_queue(): global cmd_queue return cmd_queue BaseManager.register( "get_knowledge_queue", callable=get_knowledge_queue) BaseManager.register("get_s2t_queue", callable=get_s2t_queue) BaseManager.register("get_t2s_queue", callable=get_t2s_queue) BaseManager.register("get_cmd_queue", callable=get_cmd_queue) manager = BaseManager( address=("", self._out_port), authkey=public_authkey.encode()) manager.start() print("listen on address: {}".format(manager._address)) print("public authkey: {}".format(public_authkey)) return manager
def register_teacher(self, in_path=None, in_address=None): """Register one teacher model and assign the order number to it as its id, with the file path (offline mode) or IP address (online mode) that the teacher model wrote knowledge data to. Args: in_path (str|None): The input file path. Default None. in_address (str|None): The input IP address, in the format "<IP address>:<IP port>" (e.g. "127.0.0.1:8080"). Default None. """ if self._started: raise ValueError( "The student has been started and cannot register " "teacher no longer!") if in_path and in_address: raise ValueError("Input path and input address should not " "be given at the same time!") if not in_path and not in_address: raise ValueError("One of input path and input address should " "be given when registering teacher!") if in_address: if in_address in self._in_addresses: print("WARNING: the teacher with input address {} has been " "registered, and ignored this time!".format(in_path)) return ip, port = in_address.strip().split(":") BaseManager.register("get_knowledge_queue") BaseManager.register("get_s2t_queue") BaseManager.register("get_t2s_queue") BaseManager.register("get_cmd_queue") manager = BaseManager(address=(ip, int(port)), authkey=public_authkey.encode()) # Wait for teacher model started to establish connection print("Connecting to {}, with public key {} ...".format( in_address, public_authkey)) while True: try: manager.connect() break except: time.sleep(1.0) knowledge_queue = manager.get_knowledge_queue() self._t2s_queues.append(manager.get_t2s_queue()) self._s2t_queues.append(manager.get_s2t_queue()) self._cmd_queues.append(manager.get_cmd_queue()) self._in_addresses.append(in_address) self._in_paths.append(None) print("Registered teacher {} with input address {}.".format( self._num_teachers, in_address)) else: if in_path in self._in_paths: print("WARNING: th teacher with input path {} has been " "registered, and ignored this time!".format(in_path)) return def read_offline(in_path, cmd_queue, out_queue): end_recved = False def get_cmd(): cmd, end_recved = None, False try: if not cmd_queue.empty(): cmd = cmd_queue.get() cmd_queue.task_done() if isinstance(cmd, EndSignal): end_recved = True except IOError: end_recved = True return cmd, end_recved # wait for the sync in start while not end_recved: cmd, end_recved = get_cmd() if isinstance(cmd, SyncSignal): out_queue.put(SyncSignal()) break # for multiple-times offline serving while not end_recved: # wait for the sync in get_knowledge_desc() while not end_recved: cmd, end_recved = get_cmd() if isinstance(cmd, SyncSignal): out_queue.put(SyncSignal()) break if end_recved: break with open(in_path, 'rb') as fin: # get knowledge desc desc = pickle.load(fin) out_queue.put(desc) # wait for the data accessing signal while not end_recved: cmd, end_recved = get_cmd() if isinstance(cmd, StartSignal): break # get knowledge data while not end_recved: try: data = pickle.load(fin) out_queue.put(data) _, end_recved = get_cmd() except EOFError: break if end_recved: break out_queue.put(EndSignal()) out_queue.join() knowledge_queue = Manager().Queue(100) cmd_queue = Manager().Queue(5) p = Process(target=read_offline, args=(in_path, cmd_queue, knowledge_queue)) p.daemon = True p.start() self._t2s_queues.append(None) self._s2t_queues.append(None) self._cmd_queues.append(cmd_queue) self._in_addresses.append(None) self._in_paths.append(in_path) print("Registered teacher {} with input path {}.".format( self._num_teachers, in_path)) self._teacher_knowledge_queues.append(knowledge_queue) self._num_teachers += 1
def register_teacher(self, in_path=None, in_address=None): """Register one teacher model and assign the order number to it as its id, with the file path (offline mode) or IP address (online mode) that the teacher model wrote knowledge data to. Args: in_path (str|None): The input file path. Default None. in_address (str|None): The input IP address, in the format "<IP address>:<IP port>" (e.g. "127.0.0.1:8080"). Default None. """ if self._started: raise ValueError( "The student has been started and cannot register " "teacher no longer!") if in_path and in_address: raise ValueError("Input path and input address should not " "be given at the same time!") if not in_path and not in_address: raise ValueError("One of input path and input address should " "be given when registering teacher!") if in_address: if in_address in self._in_addresses: print("WARNING: the teacher with input address {} has been " "registered, and ignored this time!".format(in_path)) return ip, port = in_address.strip().split(":") BaseManager.register("get_knowledge_queue") BaseManager.register("get_s2t_queue") BaseManager.register("get_t2s_queue") BaseManager.register("get_cmd_queue") manager = BaseManager(address=(ip, int(port)), authkey=public_authkey.encode()) print("Connecting to {}, with public key {} ...".format( in_address, public_authkey)) # Wait for teacher model started to establish connection while True: try: manager.connect() break except: time.sleep(1.0) def merge(knowledge_queues): num = len(knowledge_queues) if num == 1: return knowledge_queues[0] local_queues = [Queue.Queue(100) for _ in range(num)] def receive(queue, local_queue): while True: try: data = queue.get() queue.task_done() local_queue.put(data) except EOFError: break knowledge_queue = Queue.Queue(100) def gather(local_queues, knowledge_queue): num = len(local_queues) end_received = [0] * num while True: try: for i in range(num): data = local_queues[i].get() local_queues[i].task_done() if isinstance(data, SyncSignal): if i == 0: knowledge_queue.put(data) elif isinstance(data, EndSignal): end_received[i] = 1 if i == 0: knowledge_queue.put(data) if sum(end_received) == num: end_received = [0] * num break else: knowledge_queue.put(data) except EOFError: break # threads to receive knowledge from the online teacher for i in range(num): p = Thread(target=receive, args=(knowledge_queues[i], local_queues[i])) p.daemon = True p.start() # thread to gather data from different local queues p = Thread(target=gather, args=(local_queues, knowledge_queue)) p.daemon = True p.start() return knowledge_queue # get knowledge queues knowledge_queues, idx = [], 0 while True: q = manager.get_knowledge_queue(idx) if hasattr(q, "get"): knowledge_queues.append(q) idx += 1 else: break knowledge_queue = merge(knowledge_queues) self._t2s_queues.append(manager.get_t2s_queue()) self._s2t_queues.append(manager.get_s2t_queue()) self._cmd_queues.append(manager.get_cmd_queue()) self._in_addresses.append(in_address) self._in_paths.append(None) print("Registered teacher {} with input address {}.".format( self._num_teachers, in_address)) else: if in_path in self._in_paths: print("WARNING: th teacher with input path {} has been " "registered, and ignored this time!".format(in_path)) return def read_offline(in_path, cmd_queue, out_queue): end_recved = False def get_cmd(): cmd, end_recved = None, False try: if not cmd_queue.empty(): cmd = cmd_queue.get() cmd_queue.task_done() if isinstance(cmd, EndSignal): end_recved = True except IOError: end_recved = True return cmd, end_recved # wait for the sync in start while not end_recved: cmd, end_recved = get_cmd() if isinstance(cmd, SyncSignal): out_queue.put(SyncSignal()) break # for multiple-times offline serving while not end_recved: # wait for the sync in get_knowledge_desc() while not end_recved: cmd, end_recved = get_cmd() if isinstance(cmd, SyncSignal): out_queue.put(SyncSignal()) break if end_recved: break with open(in_path, 'rb') as fin: # get knowledge desc desc = pickle.load(fin) out_queue.put(desc) # wait for the data accessing signal while not end_recved: cmd, end_recved = get_cmd() if isinstance(cmd, StartSignal): break # get knowledge data while not end_recved: try: data = pickle.load(fin) out_queue.put(data) _, end_recved = get_cmd() except EOFError: break if end_recved: break out_queue.put(EndSignal()) out_queue.join() knowledge_queue = Queue.Queue(100) cmd_queue = Queue.Queue(5) p = Thread(target=read_offline, args=(in_path, cmd_queue, knowledge_queue)) p.daemon = True p.start() self._t2s_queues.append(None) self._s2t_queues.append(None) self._cmd_queues.append(cmd_queue) self._in_addresses.append(None) self._in_paths.append(in_path) print("Registered teacher {} with input path {}.".format( self._num_teachers, in_path)) self._teacher_knowledge_queues.append(knowledge_queue) self._num_teachers += 1