Clone this net, including only ops that are necessary in order to compute `outputs` given `inputs`. Return references to the cloned outputs. Internal blobs (blobs that are produced and consumed inside the net but not used as outputs) will be remapped to avoid name
(self, name, inputs, outputs, remap_funcs=None)
| 1799 | return new_net |
| 1800 | |
| 1801 | def ClonePartial(self, name, inputs, outputs, remap_funcs=None): |
| 1802 | """ |
| 1803 | Clone this net, including only ops that are necessary in order to |
| 1804 | compute `outputs` given `inputs`. Return references to the cloned |
| 1805 | outputs. Internal blobs (blobs that are produced and consumed inside |
| 1806 | the net but not used as outputs) will be remapped to avoid name |
| 1807 | conflict. |
| 1808 | |
| 1809 | Args: |
| 1810 | name: the name of the cloned net |
| 1811 | inputs: map where the keys correspond to BlobReferences in the |
| 1812 | original net, and the values correspond to external inputs |
| 1813 | in the partially cloned net. If `inputs` is a list, don't |
| 1814 | remap input names. |
| 1815 | outputs: outputs to be produced by the cloned net. |
| 1816 | |
| 1817 | Returns: |
| 1818 | Tuple (new_net, new_outputs) |
| 1819 | new_net: a new Net object. |
| 1820 | new_outputs: list of BlobReferences corresponding to the |
| 1821 | outputs produced by new_net. |
| 1822 | """ |
| 1823 | input_is_pair_list = isinstance(inputs, list) and all( |
| 1824 | isinstance(i, tuple) and len(i) == 2 for i in inputs) |
| 1825 | inputs = ( |
| 1826 | inputs if isinstance(inputs, (dict, OrderedDict)) else |
| 1827 | OrderedDict(inputs) if input_is_pair_list else |
| 1828 | OrderedDict(zip(inputs, inputs))) |
| 1829 | for output in outputs: |
| 1830 | assert self.BlobIsDefined(output), "{} is not defined".format(output) |
| 1831 | input_names = {str(k): str(v) for k, v in inputs.items()} |
| 1832 | output_names = [str(o) for o in outputs] |
| 1833 | proto = self._net |
| 1834 | blob_versions = {str(i): 0 for i in inputs} |
| 1835 | ssa, blob_versions = get_ssa(proto, blob_versions) |
| 1836 | used_op_ids = get_op_ids_in_path(ssa, blob_versions, inputs, outputs) |
| 1837 | disallowed_op_ids = get_op_ids_in_path(ssa, blob_versions, [], inputs) |
| 1838 | assert len(set(used_op_ids) & set(disallowed_op_ids)) == 0, ( |
| 1839 | 'Cannot partially clone net: some of the ops required would ' + |
| 1840 | 'generate the given input.') |
| 1841 | |
| 1842 | sub_ssa = [op for i, op in enumerate(ssa) if i in used_op_ids] |
| 1843 | undef_blobs = get_undefined_blobs(sub_ssa) - set(input_names.keys()) |
| 1844 | prefix = (name + '/') if name else '' |
| 1845 | |
| 1846 | def remap(blob_name): |
| 1847 | if blob_name in input_names: |
| 1848 | return input_names[blob_name] |
| 1849 | elif blob_name in undef_blobs: |
| 1850 | return blob_name |
| 1851 | else: |
| 1852 | return prefix + blob_name |
| 1853 | |
| 1854 | blob_mapping = {b: remap(b) for b in blob_versions.keys()} |
| 1855 | new_net = self.Clone(name, blob_mapping, used_op_ids, remap_funcs) |
| 1856 | new_in = [ |
| 1857 | blob_mapping[i] for i in input_names.keys()] + list(undef_blobs) |
| 1858 | new_out = [blob_mapping[o] for o in output_names] |