Skip to content

Commit 1ba62f1

Browse files
ppwwyyxxfacebook-github-bot
authored andcommitted
write to_instances as separate functions instead
Summary: jit.unused methods cannot be used on scripted classes after pytorch/pytorch#44324 Reviewed By: theschnitz Differential Revision: D26273064 fbshipit-source-id: 6858a07cf93c373bd62c86869f7ef9c7a88869df
1 parent 3c0509e commit 1ba62f1

File tree

5 files changed

+33
-25
lines changed

5 files changed

+33
-25
lines changed

detectron2/export/torchscript_patch.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,10 @@ def _clear_jit_cache():
2727

2828
def _add_instances_conversion_methods(newInstances):
2929
"""
30-
Add to_instances/from_instances methods to the scripted Instances class.
30+
Add from_instances methods to the scripted Instances class.
3131
"""
3232
cls_name = newInstances.__name__
3333

34-
@torch.jit.unused
35-
def to_instances(self):
36-
"""
37-
Convert scripted Instances to original Instances
38-
"""
39-
ret = Instances(self.image_size)
40-
for name in self._field_names:
41-
val = getattr(self, "_" + name, None)
42-
if val is not None:
43-
ret.set(name, val)
44-
return ret
45-
4634
@torch.jit.unused
4735
def from_instances(instances: Instances):
4836
"""
@@ -56,7 +44,6 @@ def from_instances(instances: Instances):
5644
setattr(ret, name, deepcopy(val))
5745
return ret
5846

59-
newInstances.to_instances = to_instances
6047
newInstances.from_instances = from_instances
6148

6249

detectron2/utils/testing.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from detectron2.data import DatasetCatalog
88
from detectron2.data.detection_utils import read_image
99
from detectron2.modeling import build_model
10-
from detectron2.structures import Boxes
10+
from detectron2.structures import Boxes, Instances
1111
from detectron2.utils.file_io import PathManager
1212

1313

@@ -50,7 +50,7 @@ def get_sample_coco_image(tensor=True):
5050
an image, in BGR color.
5151
"""
5252
try:
53-
file_name = DatasetCatalog.get("coco_2017_train")[0]["file_name"]
53+
file_name = DatasetCatalog.get("coco_2017_val_100")[0]["file_name"]
5454
if not PathManager.exists(file_name):
5555
raise FileNotFoundError()
5656
except IOError:
@@ -62,13 +62,30 @@ def get_sample_coco_image(tensor=True):
6262
return ret
6363

6464

65+
def convert_scripted_instances(instances):
66+
"""
67+
Convert a scripted Instances object to a regular :class:`Instances` object
68+
"""
69+
ret = Instances(instances.image_size)
70+
for name in instances._field_names:
71+
val = getattr(instances, "_" + name, None)
72+
if val is not None:
73+
ret.set(name, val)
74+
return ret
75+
76+
6577
def assert_instances_allclose(input, other, *, rtol=1e-5, msg="", size_as_tensor=False):
6678
"""
6779
Args:
6880
input, other (Instances):
6981
size_as_tensor: compare image_size of the Instances as tensors (instead of tuples).
7082
Useful for comparing outputs of tracing.
7183
"""
84+
if not isinstance(input, Instances):
85+
input = convert_scripted_instances(input)
86+
if not isinstance(other, Instances):
87+
other = convert_scripted_instances(other)
88+
7289
if not msg:
7390
msg = "Two Instances are different! "
7491
else:

tests/modeling/test_roi_heads.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ def test_mask_head_scriptability(self):
190190
script_outputs = sciript_mask_head(mask_features, [pred_instance0, pred_instance1])
191191

192192
for origin_ins, script_ins in zip(origin_outputs, script_outputs):
193-
assert_instances_allclose(origin_ins, script_ins.to_instances(), rtol=0)
193+
assert_instances_allclose(origin_ins, script_ins, rtol=0)
194194

195195
@unittest.skipIf(TORCH_VERSION < (1, 8), "Insufficient pytorch version")
196196
def test_keypoint_head_scriptability(self):
@@ -226,7 +226,7 @@ def test_keypoint_head_scriptability(self):
226226
)
227227

228228
for origin_ins, script_ins in zip(origin_outputs, script_outputs):
229-
assert_instances_allclose(origin_ins, script_ins.to_instances(), rtol=0)
229+
assert_instances_allclose(origin_ins, script_ins, rtol=0)
230230

231231
@unittest.skipIf(TORCH_VERSION < (1, 8), "Insufficient pytorch version")
232232
def test_StandardROIHeads_scriptability(self):
@@ -278,7 +278,7 @@ def test_StandardROIHeads_scriptability(self):
278278
scripted_pred_instances, _ = scripted_rot_heads(images, features, proposals)
279279

280280
for instance, scripted_instance in zip(pred_instances, scripted_pred_instances):
281-
assert_instances_allclose(instance, scripted_instance.to_instances(), rtol=0)
281+
assert_instances_allclose(instance, scripted_instance, rtol=0)
282282

283283
@unittest.skipIf(TORCH_VERSION < (1, 8), "Insufficient pytorch version")
284284
def test_PointRend_mask_head_tracing(self):

tests/structures/test_instances.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from detectron2.export.torchscript import patch_instances
77
from detectron2.structures import Boxes, Instances
88
from detectron2.utils.env import TORCH_VERSION
9+
from detectron2.utils.testing import convert_scripted_instances
910

1011

1112
class TestInstances(unittest.TestCase):
@@ -182,7 +183,7 @@ def test_from_to_instances(self):
182183
with patch_instances(fields) as NewInstances:
183184
# convert to NewInstances and back
184185
new1 = NewInstances.from_instances(orig)
185-
new2 = new1.to_instances()
186+
new2 = convert_scripted_instances(new1)
186187
self.assertTrue(torch.equal(orig.proposal_boxes.tensor, new1.proposal_boxes.tensor))
187188
self.assertTrue(torch.equal(orig.proposal_boxes.tensor, new2.proposal_boxes.tensor))
188189

tests/test_export_torchscript.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
from detectron2.modeling.roi_heads import KRCNNConvDeconvUpsampleHead
1818
from detectron2.structures import Boxes, Instances
1919
from detectron2.utils.env import TORCH_VERSION
20-
from detectron2.utils.testing import assert_instances_allclose, get_sample_coco_image, random_boxes
20+
from detectron2.utils.testing import (
21+
assert_instances_allclose,
22+
convert_scripted_instances,
23+
get_sample_coco_image,
24+
random_boxes,
25+
)
2126

2227

2328
"""
@@ -53,9 +58,7 @@ def _test_rcnn_model(self, config_path):
5358
inputs = [{"image": get_sample_coco_image()}]
5459
with torch.no_grad():
5560
instance = model.inference(inputs, do_postprocess=False)[0]
56-
scripted_instance = script_model.inference(inputs, do_postprocess=False)[
57-
0
58-
].to_instances()
61+
scripted_instance = script_model.inference(inputs, do_postprocess=False)[0]
5962
assert_instances_allclose(instance, scripted_instance)
6063

6164
def _test_retinanet_model(self, config_path):
@@ -73,7 +76,7 @@ def _test_retinanet_model(self, config_path):
7376
inputs = [{"image": img}]
7477
with torch.no_grad():
7578
instance = model(inputs)[0]["instances"]
76-
scripted_instance = script_model(inputs)[0].to_instances()
79+
scripted_instance = convert_scripted_instances(script_model(inputs)[0])
7780
scripted_instance = detector_postprocess(scripted_instance, img.shape[1], img.shape[2])
7881
assert_instances_allclose(instance, scripted_instance)
7982
# Note that the model currently cannot be saved and loaded into a new process:

0 commit comments

Comments
 (0)