Main entry for the master device in each forward pass. The messages were first collected from each devices (including the master device), and then an callback will be invoked to compute the message to be sent back to each devices (including the master device).
(self, master_msg)
| 94 | return SlavePipe(identifier, self._queue, future) |
| 95 | |
| 96 | def run_master(self, master_msg): |
| 97 | """ |
| 98 | Main entry for the master device in each forward pass. |
| 99 | The messages were first collected from each devices (including the master device), and then |
| 100 | an callback will be invoked to compute the message to be sent back to each devices |
| 101 | (including the master device). |
| 102 | |
| 103 | Args: |
| 104 | master_msg: the message that the master want to send to itself. This will be placed as the first |
| 105 | message when calling `master_callback`. For detailed usage, see `_SynchronizedBatchNorm` for an example. |
| 106 | |
| 107 | Returns: the message to be sent back to the master device. |
| 108 | |
| 109 | """ |
| 110 | self._activated = True |
| 111 | |
| 112 | intermediates = [(0, master_msg)] |
| 113 | for i in range(self.nr_slaves): |
| 114 | intermediates.append(self._queue.get()) |
| 115 | |
| 116 | results = self._master_callback(intermediates) |
| 117 | assert results[0][0] == 0, 'The first result should belongs to the master.' |
| 118 | |
| 119 | for i, res in results: |
| 120 | if i == 0: |
| 121 | continue |
| 122 | self._registry[i].result.put(res) |
| 123 | |
| 124 | for i in range(self.nr_slaves): |
| 125 | assert self._queue.get() is True |
| 126 | |
| 127 | return results[0][1] |
| 128 | |
| 129 | @property |
| 130 | def nr_slaves(self): |