Args: inputs (tuple[torch.Tensor]) Returns: dict[str, torch.Tensor]
(self, inputs)
| 69 | return output_devices |
| 70 | |
| 71 | def forward(self, inputs): |
| 72 | """ |
| 73 | Args: |
| 74 | inputs (tuple[torch.Tensor]) |
| 75 | |
| 76 | Returns: |
| 77 | dict[str, torch.Tensor] |
| 78 | """ |
| 79 | assert len(inputs) == len(self._input_blobs), ( |
| 80 | f"Length of inputs ({len(inputs)}) " |
| 81 | f"doesn't match the required input blobs: {self._input_blobs}" |
| 82 | ) |
| 83 | |
| 84 | with ScopedWS(self.ws_name, is_reset=False, is_cleanup=False) as ws: |
| 85 | for b, tensor in zip(self._input_blobs, inputs): |
| 86 | ws.FeedBlob(b, tensor) |
| 87 | |
| 88 | try: |
| 89 | ws.RunNet(self.net.Proto().name) |
| 90 | except RuntimeError as e: |
| 91 | if not str(e) in self._error_msgs: |
| 92 | self._error_msgs.add(str(e)) |
| 93 | logger.warning("Encountered new RuntimeError: \n{}".format(str(e))) |
| 94 | logger.warning("Catch the error and use partial results.") |
| 95 | |
| 96 | c2_outputs = [ws.FetchBlob(b) for b in self.net.Proto().external_output] |
| 97 | # Remove outputs of current run, this is necessary in order to |
| 98 | # prevent fetching the result from previous run if the model fails |
| 99 | # in the middle. |
| 100 | for b in self.net.Proto().external_output: |
| 101 | # Needs to create uninitialized blob to make the net runable. |
| 102 | # This is "equivalent" to: ws.RemoveBlob(b) then ws.CreateBlob(b), |
| 103 | # but there'no such API. |
| 104 | ws.FeedBlob(b, f"{b}, a C++ native class of type nullptr (uninitialized).") |
| 105 | |
| 106 | # Cast output to torch.Tensor on the desired device |
| 107 | output_devices = ( |
| 108 | self._infer_output_devices(inputs) |
| 109 | if any(t.device.type != "cpu" for t in inputs) |
| 110 | else ["cpu" for _ in self.net.Proto().external_output] |
| 111 | ) |
| 112 | |
| 113 | outputs = [] |
| 114 | for name, c2_output, device in zip( |
| 115 | self.net.Proto().external_output, c2_outputs, output_devices |
| 116 | ): |
| 117 | if not isinstance(c2_output, np.ndarray): |
| 118 | raise RuntimeError( |
| 119 | "Invalid output for blob {}, received: {}".format(name, c2_output) |
| 120 | ) |
| 121 | outputs.append(torch.Tensor(c2_output).to(device=device)) |
| 122 | # TODO change to tuple in the future |
| 123 | return dict(zip(self.net.Proto().external_output, outputs)) |
| 124 | |
| 125 | |
| 126 | class ProtobufDetectionModel(torch.nn.Module): |
nothing calls this directly
no test coverage detected