3
3
#include " core/conversion/converters/converters.h"
4
4
#include " NvInfer.h"
5
5
#include " plugins/interpolate_plugin.h"
6
+ #include " NvInferRuntimeCommon.h"
6
7
7
- #include < csignal >
8
+ #include < tuple >
8
9
9
10
namespace trtorch {
10
11
namespace core {
@@ -13,12 +14,75 @@ namespace converters {
13
14
namespace impl {
14
15
namespace {
15
16
17
+ /*
18
+ * Helper functions
19
+ */
20
+
21
+ auto parse_nearest (args args) {
22
+ auto in = args[0 ].ITensor ();
23
+ auto in_shape = util::toVec (in->getDimensions ());
24
+
25
+ return std::make_tuple (in, in_shape);
26
+ }
27
+
28
+ auto parse_linear (args args) {
29
+ auto in = args[0 ].ITensor ();
30
+ auto in_shape = util::toVec (in->getDimensions ());
31
+ bool align_corners = args[2 ].unwrapToBool ();
32
+
33
+ return std::make_tuple (in, in_shape, align_corners);
34
+ }
35
+
36
+ void create_plugin (ConversionCtx* ctx, const torch::jit::Node* n, nvinfer1::ITensor* in, const char * name,
37
+ std::vector<int64_t > in_shape,
38
+ std::vector<int64_t > out_shape,
39
+ std::vector<int64_t > out_size,
40
+ std::string mode) {
41
+ auto creator = new plugins::InterpolatePluginCreator ();
42
+ auto plugin = creator->createPlugin (name, in_shape, out_shape, out_size, mode, false );
43
+
44
+ auto resize_layer = ctx->net ->addPluginV2 (reinterpret_cast <nvinfer1::ITensor* const *>(&in), 1 , *plugin);
45
+ TRTORCH_CHECK (resize_layer, " Unable to create interpolation plugin from node" << *n);
46
+
47
+ resize_layer->setName (util::node_info (n).c_str ());
48
+
49
+ auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
50
+
51
+ LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
52
+ }
53
+
54
+ void resize_layer_size (ConversionCtx* ctx, const torch::jit::Node* n, nvinfer1::ITensor* in, std::vector<int64_t > out_shape,
55
+ nvinfer1::ResizeMode mode) {
56
+ auto resize_layer = ctx->net ->addResize (*in);
57
+ TRTORCH_CHECK (resize_layer, " Unable to create interpolation (resizing) layer from node" << *n);
58
+
59
+ resize_layer->setOutputDimensions (util::toDims (out_shape));
60
+ resize_layer->setResizeMode (mode);
61
+ resize_layer->setName (util::node_info (n).c_str ());
62
+
63
+ // if interpolation mode is linear, align corners must have been set to true. else, don't use align corners.
64
+ if (mode == nvinfer1::ResizeMode::kLINEAR ) {
65
+ resize_layer->setAlignCorners (true );
66
+ }
67
+
68
+ auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
69
+
70
+ LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
71
+ }
72
+
73
+
74
+ /*
75
+ * Interpolate Converter
76
+ */
77
+
16
78
auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
17
79
.pattern({
18
80
" aten::upsample_nearest1d(Tensor self, int[1] output_size, float? scales=None) -> (Tensor)" ,
19
81
[](ConversionCtx* ctx, const torch::jit::Node* n, args& args) -> bool {
20
- auto in = args[0 ].ITensor ();
21
- auto in_shape = util::toVec (in->getDimensions ());
82
+ auto parsed = parse_nearest (args);
83
+
84
+ auto in = std::get<0 >(parsed);
85
+ auto in_shape = std::get<1 >(parsed);
22
86
23
87
// Case 1: user uses output size and not scales
24
88
if (!args[1 ].IValue ()->isNone () && args[2 ].IValue ()->isNone ()) {
@@ -29,15 +93,7 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
29
93
auto out_shape = in_shape;
30
94
std::copy (out_size.begin (), out_size.end (), out_shape.begin () + (in_shape.size () - out_size.size ()));
31
95
32
- auto resize_layer = ctx->net ->addResize (*in);
33
- TRTORCH_CHECK (resize_layer, " Unable to create interpolation (resizing) layer from node" << *n);
34
-
35
- resize_layer->setOutputDimensions (util::toDims (out_shape));
36
- resize_layer->setResizeMode (nvinfer1::ResizeMode::kNEAREST );
37
- resize_layer->setName (util::node_info (n).c_str ());
38
-
39
- auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
40
- LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
96
+ resize_layer_size (ctx, n, in, out_shape, nvinfer1::ResizeMode::kNEAREST );
41
97
} else {
42
98
TRTORCH_THROW_ERROR (" Unable to convert node: " << util::node_info (n) << " \n Scale factor parameter for upsample_nearest1d not supported yet." );
43
99
}
@@ -47,8 +103,10 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
47
103
}).pattern({
48
104
" aten::upsample_nearest2d(Tensor self, int[2] output_size, float? scales_h=None, float? scales_w=None) -> (Tensor)" ,
49
105
[](ConversionCtx* ctx, const torch::jit::Node* n, args& args) -> bool {
50
- auto in = args[0 ].ITensor ();
51
- auto in_shape = util::toVec (in->getDimensions ());
106
+ auto parsed = parse_nearest (args);
107
+
108
+ auto in = std::get<0 >(parsed);
109
+ auto in_shape = std::get<1 >(parsed);
52
110
53
111
// Case 1: user uses output_size and not scales_h, scales_w
54
112
if (!args[1 ].IValue ()->isNone () && args[2 ].IValue ()->isNone () && args[3 ].IValue ()->isNone ()){
@@ -59,15 +117,7 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
59
117
auto out_shape = in_shape;
60
118
std::copy (out_size.begin (), out_size.end (), out_shape.begin () + (in_shape.size () - out_size.size ()));
61
119
62
- auto resize_layer = ctx->net ->addResize (*in);
63
- TRTORCH_CHECK (resize_layer, " Unable to create interpolation (resizing) layer from node" << *n);
64
-
65
- resize_layer->setOutputDimensions (util::toDims (out_shape));
66
- resize_layer->setResizeMode (nvinfer1::ResizeMode::kNEAREST );
67
- resize_layer->setName (util::node_info (n).c_str ());
68
-
69
- auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
70
- LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
120
+ resize_layer_size (ctx, n, in, out_shape, nvinfer1::ResizeMode::kNEAREST );
71
121
} else {
72
122
TRTORCH_THROW_ERROR (" Unable to convert node: " << util::node_info (n) << " \n Scale factor parameter for upsample_nearest2d not supported yet." );
73
123
}
@@ -77,8 +127,10 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
77
127
}).pattern({
78
128
" aten::upsample_nearest3d(Tensor self, int[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> (Tensor)" ,
79
129
[](ConversionCtx* ctx, const torch::jit::Node* n, args& args) -> bool {
80
- auto in = args[0 ].ITensor ();
81
- auto in_shape = util::toVec (in->getDimensions ());
130
+ auto parsed = parse_nearest (args);
131
+
132
+ auto in = std::get<0 >(parsed);
133
+ auto in_shape = std::get<1 >(parsed);
82
134
83
135
// Case 1: user uses output size and not scales_d, scales_h, scales_w
84
136
if (!args[1 ].IValue ()->isNone () && args[2 ].IValue ()->isNone () && args[3 ].IValue ()->isNone () && args[4 ].IValue ()->isNone ()) {
@@ -88,16 +140,8 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
88
140
89
141
auto out_shape = in_shape;
90
142
std::copy (out_size.begin (), out_size.end (), out_shape.begin () + (in_shape.size () - out_size.size ()));
91
-
92
- auto resize_layer = ctx->net ->addResize (*in);
93
- TRTORCH_CHECK (resize_layer, " Unable to create interpolation (resizing) layer from node" << *n);
94
-
95
- resize_layer->setOutputDimensions (util::toDims (out_shape));
96
- resize_layer->setResizeMode (nvinfer1::ResizeMode::kNEAREST );
97
- resize_layer->setName (util::node_info (n).c_str ());
98
143
99
- auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
100
- LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
144
+ resize_layer_size (ctx, n, in, out_shape, nvinfer1::ResizeMode::kNEAREST );
101
145
} else {
102
146
TRTORCH_THROW_ERROR (" Unable to convert node: " << util::node_info (n) << " \n Scale factor parameter for upsample_nearest3d not supported yet." );
103
147
}
@@ -107,10 +151,11 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
107
151
}).pattern({
108
152
" aten::upsample_linear1d(Tensor self, int[1] output_size, bool align_corners, float? scales=None) -> (Tensor)" ,
109
153
[](ConversionCtx* ctx, const torch::jit::Node* n, args& args) -> bool {
110
- auto in = args[0 ].ITensor ();
111
- auto in_shape = util::toVec (in->getDimensions ());
112
-
113
- bool align_corners = args[2 ].unwrapToBool ();
154
+ auto parsed = parse_linear (args);
155
+
156
+ auto in = std::get<0 >(parsed);
157
+ auto in_shape = std::get<1 >(parsed);
158
+ auto align_corners = std::get<2 >(parsed);
114
159
115
160
// Case 1: user uses output size and not scales
116
161
if (!args[1 ].IValue ()->isNone () && args[3 ].IValue ()->isNone ()) {
@@ -122,34 +167,10 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
122
167
std::copy (out_size.begin (), out_size.end (), out_shape.begin () + (in_shape.size () - out_size.size ()));
123
168
124
169
if (!align_corners) {
125
- // auto plugin = creator->createPlugin(util::node_info(n).c_str(), in_shape, out_shape, out_size, std::string("linear"), align_corners);
126
- std::raise (SIGINT);
127
-
128
- // auto creator_auto = getPluginRegistry()->getPluginCreator("interpolate", "1");
129
- // auto plugin_auto = creator_auto->createPlugin(util::node_info(n).c_str(), nullptr);
130
-
131
- // auto creator = getPluginRegistry()->getPluginCreator("interpolate", "1");
132
-
133
- auto creator = new plugins::InterpolatePluginCreator ();
134
- auto plugin = creator->createPlugin (" interpolate_plugin" , in_shape, out_shape, out_size, std::string (" linear" ), align_corners);
135
-
136
- auto resize_layer = ctx->net ->addPluginV2 (reinterpret_cast <nvinfer1::ITensor* const *>(&in), 1 , *plugin);
137
- resize_layer->setName (util::node_info (n).c_str ());
138
-
139
- auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
140
-
141
- LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
170
+ // align_corners not supported in TensorRT, create plugin and run layer through PyTorch
171
+ create_plugin (ctx, n, in, " linear1d" , in_shape, out_shape, out_size, std::string (" linear" ));
142
172
} else {
143
- auto resize_layer = ctx->net ->addResize (*in);
144
- TRTORCH_CHECK (resize_layer, " Unable to create interpolation (resizing) layer from node" << *n);
145
-
146
- resize_layer->setOutputDimensions (util::toDims (out_shape));
147
- resize_layer->setResizeMode (nvinfer1::ResizeMode::kLINEAR );
148
- resize_layer->setAlignCorners (align_corners);
149
- resize_layer->setName (util::node_info (n).c_str ());
150
-
151
- auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
152
- LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
173
+ resize_layer_size (ctx, n, in, out_shape, nvinfer1::ResizeMode::kLINEAR );
153
174
}
154
175
} else {
155
176
TRTORCH_THROW_ERROR (" Unable to convert node: " << util::node_info (n) << " \n Scale factor parameter for upsample_linear1d not supported yet." );
@@ -160,10 +181,11 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
160
181
}).pattern({
161
182
" aten::upsample_bilinear2d(Tensor self, int[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> (Tensor)" ,
162
183
[](ConversionCtx* ctx, const torch::jit::Node* n, args& args) -> bool {
163
- auto in = args[0 ].ITensor ();
164
- auto in_shape = util::toVec (in->getDimensions ());
165
-
166
- bool align_corners = args[2 ].IValue ()->to <bool >();
184
+ auto parsed = parse_linear (args);
185
+
186
+ auto in = std::get<0 >(parsed);
187
+ auto in_shape = std::get<1 >(parsed);
188
+ auto align_corners = std::get<2 >(parsed);
167
189
168
190
// Case 1: user uses output size and not scales_h, scales_w
169
191
if (!args[1 ].IValue ()->isNone () && args[3 ].IValue ()->isNone () && args[4 ].IValue ()->isNone ()) {
@@ -174,16 +196,12 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
174
196
auto out_shape = in_shape;
175
197
std::copy (out_size.begin (), out_size.end (), out_shape.begin () + (in_shape.size () - out_size.size ()));
176
198
177
- auto resize_layer = ctx->net ->addResize (*in);
178
- TRTORCH_CHECK (resize_layer, " Unable to create interpolation (resizing) layer from node" << *n);
179
-
180
- resize_layer->setOutputDimensions (util::toDims (out_shape));
181
- resize_layer->setResizeMode (nvinfer1::ResizeMode::kLINEAR );
182
- resize_layer->setAlignCorners (align_corners);
183
- resize_layer->setName (util::node_info (n).c_str ());
184
-
185
- auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
186
- LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
199
+ if (!align_corners) {
200
+ // align_corners not supported in TensorRT, create plugin and run layer through PyTorch
201
+ create_plugin (ctx, n, in, " bilinear2d" , in_shape, out_shape, out_size, std::string (" bilinear" ));
202
+ } else {
203
+ resize_layer_size (ctx, n, in, out_shape, nvinfer1::ResizeMode::kLINEAR );
204
+ }
187
205
} else {
188
206
TRTORCH_THROW_ERROR (" Unable to convert node: " << util::node_info (n) << " \n Scale factor parameter for upsample_bilinear2d not supported yet." );
189
207
}
@@ -193,10 +211,11 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
193
211
}).pattern({
194
212
" aten::upsample_trilinear3d(Tensor self, int[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> (Tensor)" ,
195
213
[](ConversionCtx* ctx, const torch::jit::Node* n, args& args) -> bool {
196
- auto in = args[0 ].ITensor ();
197
- auto in_shape = util::toVec (in->getDimensions ());
198
-
199
- bool align_corners = args[2 ].IValue ()->to <bool >();
214
+ auto parsed = parse_linear (args);
215
+
216
+ auto in = std::get<0 >(parsed);
217
+ auto in_shape = std::get<1 >(parsed);
218
+ auto align_corners = std::get<2 >(parsed);
200
219
201
220
// Case 1: user uses output size and not scales_d, scales_h, scales_w
202
221
if (!args[1 ].IValue ()->isNone () && args[3 ].IValue ()->isNone () && args[4 ].IValue ()->isNone () && args[5 ].IValue ()->isNone ()) {
@@ -207,16 +226,12 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
207
226
auto out_shape = in_shape;
208
227
std::copy (out_size.begin (), out_size.end (), out_shape.begin () + (in_shape.size () - out_size.size ()));
209
228
210
- auto resize_layer = ctx->net ->addResize (*in);
211
- TRTORCH_CHECK (resize_layer, " Unable to create interpolation (resizing) layer from node" << *n);
212
-
213
- resize_layer->setOutputDimensions (util::toDims (out_shape));
214
- resize_layer->setResizeMode (nvinfer1::ResizeMode::kLINEAR );
215
- resize_layer->setAlignCorners (align_corners);
216
- resize_layer->setName (util::node_info (n).c_str ());
217
-
218
- auto layer_output = ctx->AssociateValueAndTensor (n->outputs ()[0 ], resize_layer->getOutput (0 ));
219
- LOG_DEBUG (" Output tensor shape: " << layer_output->getDimensions ());
229
+ if (!align_corners) {
230
+ // align_corners not supported in TensorRT, create plugin and run layer through PyTorch
231
+ create_plugin (ctx, n, in, " trilinear3d" , in_shape, out_shape, out_size, std::string (" trilinear" ));
232
+ } else {
233
+ resize_layer_size (ctx, n, in, out_shape, nvinfer1::ResizeMode::kLINEAR );
234
+ }
220
235
} else {
221
236
TRTORCH_THROW_ERROR (" Unable to convert node: " << util::node_info (n) << " \n Scale factor parameter for upsample_trilinear3d not supported yet." );
222
237
}
@@ -225,9 +240,10 @@ auto interpolate_registrations TRTORCH_UNUSED = RegisterNodeConversionPatterns()
225
240
}
226
241
});
227
242
243
+
228
244
} // namespace
229
245
} // namespace impl
230
246
} // namespace converters
231
247
} // namespace conversion
232
248
} // namespace core
233
- } // namespace trtorch
249
+ } // namespace trtorch
0 commit comments