1
1
#include " NvInfer.h"
2
2
#include " core/conversion/converters/converters.h"
3
3
#include " core/conversion/tensorcontainer/TensorContainer.h"
4
+ #include " core/util/converter_util.h"
4
5
#include " core/util/prelude.h"
5
6
#include " core/util/trt_util.h"
6
- #include " plugins/checkshape_plugin.h"
7
7
#include " torch/torch.h"
8
8
9
9
#include < ATen/ATen.h>
@@ -16,33 +16,6 @@ namespace converters {
16
16
namespace impl {
17
17
namespace {
18
18
19
- nvinfer1::ILayer* create_plugin (
20
- ConversionCtx* ctx,
21
- const torch::jit::Node* n,
22
- nvinfer1::ITensor* inShape,
23
- nvinfer1::ITensor* expandShape,
24
- int32_t in_rank,
25
- int32_t expand_rank,
26
- const char * name) {
27
- auto creator = new plugins::CheckShapePluginCreator ();
28
- std::vector<nvinfer1::PluginField> fields;
29
- nvinfer1::PluginField input_rank (" input_rank" , &in_rank, nvinfer1::PluginFieldType::kINT32 , 1 );
30
- nvinfer1::PluginField output_rank (" expand_rank" , &expand_rank, nvinfer1::PluginFieldType::kINT32 , 1 );
31
- fields.push_back (input_rank);
32
- fields.push_back (output_rank);
33
- nvinfer1::PluginFieldCollection collection;
34
- collection.nbFields = fields.size ();
35
- collection.fields = fields.data ();
36
- auto plugin = creator->createPlugin (name, &collection);
37
-
38
- nvinfer1::ITensor* inputs[] = {inShape, expandShape};
39
- auto expandShape_layer = ctx->net ->addPluginV2 (inputs, 2 , *plugin);
40
- TRTORCH_CHECK (expandShape_layer, " Unable to create interpolation plugin from node" << *n);
41
-
42
- expandShape_layer->setName (" CheckShapePlugin" );
43
- return expandShape_layer;
44
- }
45
-
46
19
void addSliceInput (nvinfer1::Dims& dims, int idx, ConversionCtx* ctx, nvinfer1::ISliceLayer* slice) {
47
20
int32_t rank = static_cast <int32_t >(dims.nbDims );
48
21
int32_t * tmp = new int32_t [rank];
@@ -54,18 +27,12 @@ void addSliceInput(nvinfer1::Dims& dims, int idx, ConversionCtx* ctx, nvinfer1::
54
27
slice->setInput (idx, *t);
55
28
}
56
29
57
- nvinfer1::ITensor* vec2Tensor (int32_t * dim, int rank, ConversionCtx* ctx) {
58
- const nvinfer1::Dims d{1 , {static_cast <int32_t >(rank)}};
59
- const nvinfer1::Weights w{nvinfer1::DataType::kINT32 , dim, rank};
60
- return ctx->net ->addConstant (d, w)->getOutput (0 );
61
- }
62
-
63
30
nvinfer1::ITensor* concat (int max_rank, int old_rank, ConversionCtx* ctx, nvinfer1::ITensor* tensor) {
64
31
if (max_rank - old_rank > 0 ) {
65
32
int32_t * tmp = new int32_t [max_rank - old_rank];
66
33
for (int i = 0 ; i < (max_rank - old_rank); i++)
67
34
tmp[i] = 1 ;
68
- auto max_rank_tensor = vec2Tensor (tmp, max_rank - old_rank, ctx);
35
+ auto max_rank_tensor = util::arrToTensor (tmp, max_rank - old_rank, ctx);
69
36
auto in_shape_tensor = ctx->net ->addShape (*tensor)->getOutput (0 );
70
37
nvinfer1::ITensor* const args[2 ] = {max_rank_tensor, in_shape_tensor};
71
38
return ctx->net ->addConcatenation (args, 2 )->getOutput (0 );
@@ -81,11 +48,12 @@ bool add_expand(ConversionCtx* ctx, const torch::jit::Node* n, nvinfer1::ITensor
81
48
" Number of dimensions of the desired expansion must be greater than or equal to the number of input dimensions" );
82
49
83
50
// Validate the expansion. Eg: an input of [3, 1] can be expanded to [1, 3, 4] but not [3, 4, 1]
84
- for (int i = expandedDims.nbDims - 1 ; i >= 0 ; --i) {
51
+ for (int64_t i = expandedDims.nbDims - 1 ; i >= 0 ; --i) {
85
52
int64_t offset = expandedDims.nbDims - 1 - i;
86
53
int64_t dim = input_dims.nbDims - 1 - offset;
87
54
int64_t size = (dim >= 0 ) ? input_dims.d [dim] : 1 ;
88
55
int64_t targetSize = expandedDims.d [i];
56
+ // In expand layer passing -1 as the size for a dimension means not changing the size of that dimension.
89
57
if (targetSize != -1 ) {
90
58
if (size != targetSize) {
91
59
if (size != 1 ) {
@@ -96,6 +64,8 @@ bool add_expand(ConversionCtx* ctx, const torch::jit::Node* n, nvinfer1::ITensor
96
64
}
97
65
}
98
66
} else {
67
+ // For the new dimensions, the size cannot be set to -1. Eg: an input of [3, 1] can be expanded to [3, -1, 4] but
68
+ // not [-1, 3, 4].
99
69
if (dim < 0 ) {
100
70
TRTORCH_THROW_ERROR (
101
71
" The expanded size of the tensor (" << targetSize << " ) isn't allowed in a leading, non-existing dimension "
@@ -111,10 +81,10 @@ bool add_expand(ConversionCtx* ctx, const torch::jit::Node* n, nvinfer1::ITensor
111
81
if (num_expand_dims > 0 ) {
112
82
nvinfer1::Dims reshape_dims;
113
83
reshape_dims.nbDims = expandedDims.nbDims ;
114
- for (int i = 0 ; i < num_expand_dims; i++) {
84
+ for (int64_t i = 0 ; i < num_expand_dims; i++) {
115
85
reshape_dims.d [i] = 1 ;
116
86
}
117
- for (int i = 0 ; i < input_dims.nbDims ; i++) {
87
+ for (int64_t i = 0 ; i < input_dims.nbDims ; i++) {
118
88
reshape_dims.d [num_expand_dims + i] = input_dims.d [i];
119
89
}
120
90
// Add a reshape layer to expand dims
@@ -130,7 +100,7 @@ bool add_expand(ConversionCtx* ctx, const torch::jit::Node* n, nvinfer1::ITensor
130
100
131
101
// Set the stride of non singleton dimension to 1
132
102
std::vector<int64_t > strides_vec (expandedDims.nbDims , 0 );
133
- for (int i = 0 ; i < expandedDims.nbDims ; i++) {
103
+ for (int64_t i = 0 ; i < expandedDims.nbDims ; i++) {
134
104
strides_vec[i] = (in->getDimensions ().d [i] != 1 );
135
105
}
136
106
@@ -150,22 +120,51 @@ bool add_expand_dynamic(
150
120
ConversionCtx* ctx,
151
121
const torch::jit::Node* n,
152
122
nvinfer1::ITensor* in,
153
- nvinfer1::ITensor* expandedDimsTensor) {
154
- auto input_shape_tensor = ctx->net ->addShape (*in)->getOutput (0 );
123
+ nvinfer1::ITensor* expandedDimsTensor,
124
+ nvinfer1::Dims expandedDims,
125
+ bool is_expand_layer) {
126
+ auto input_dims = in->getDimensions ();
155
127
auto input_rank = in->getDimensions ().nbDims ;
156
128
auto output_rank = expandedDimsTensor->getDimensions ().d [0 ];
157
129
TRTORCH_CHECK (
158
130
input_rank <= output_rank,
159
131
" Number of dimensions of the desired expansion must be greater than or equal to the number of input dimensions" );
160
132
161
- // add a plugin to check expandedDimsTensor whether match input_shape_tensor
162
- auto expandShape_layer =
163
- create_plugin (ctx, n, input_shape_tensor, expandedDimsTensor, input_rank, output_rank, " expandShape" );
164
- auto _tensor = expandShape_layer->getOutput (0 );
133
+ /* TODO: When the inputs are dynamic, some dimensions of the inputs are indeterminate before setBindingDimensions. For
134
+ these indeterminate dimensions, we don't validate the expansion. Eg: For an input of [3, -1], we omit the
135
+ validation of the second dimension. Need to explore a better way to validate the expansion.
136
+ */
137
+ // Validate the expansion. Eg: an input of [3, 1] can be expanded to [1, 3, 4] but not [3, 4, 1]
138
+ for (int64_t i = expandedDims.nbDims - 1 ; i >= 0 ; --i) {
139
+ int64_t offset = expandedDims.nbDims - 1 - i;
140
+ int64_t dim = input_dims.nbDims - 1 - offset;
141
+ int64_t size = (dim >= 0 ) ? input_dims.d [dim] : 1 ;
142
+ int64_t targetSize = expandedDims.d [i];
143
+ // Passing -1 as the size for a dimension means not changing the size of that dimension in expand layer.
144
+ if (targetSize != -1 ) {
145
+ if (size != targetSize) {
146
+ // if size == -1, we can't validate the expansion before setBindingDimensions.
147
+ if (!(size == -1 || size == 1 )) {
148
+ TRTORCH_THROW_ERROR (
149
+ " The expanded size of tensor (" << targetSize << " )"
150
+ << " must match the existing size (" << size << " )"
151
+ << " at dimension " << i);
152
+ }
153
+ }
154
+ } else {
155
+ // In dynamic expand layer, for the new dimensions, the size cannot be set to -1. Eg: an input of [3, 1] can be
156
+ // expanded to [3, -1, 4] but not [-1, 3, 4].
157
+ if (is_expand_layer && dim < 0 ) {
158
+ TRTORCH_THROW_ERROR (
159
+ " The expanded size of the tensor (" << targetSize << " ) isn't allowed in a leading, non-existing dimension "
160
+ << i);
161
+ }
162
+ }
163
+ }
165
164
166
165
size_t max_rank = std::max (input_rank, output_rank);
167
166
168
- // Dimensions are right alignment
167
+ // Dimensions are right alignment. Eg: an input of [3, 1] and max_rank = 4, the result of concat is [1, 1, 3, 1]
169
168
auto new_input_shape_tensor = concat (max_rank, input_rank, ctx, in);
170
169
// LOG_DEBUG("Expand layer output tensor shape: " << new_output_shape_tensor->getDimensions());
171
170
auto new_output_shape_tensor = expandedDimsTensor;
@@ -189,7 +188,7 @@ bool add_expand_dynamic(
189
188
// min(1, sub(input_shape, 1))
190
189
int32_t * one_vector_tmp = new int32_t [1 ];
191
190
one_vector_tmp[0 ] = 1 ;
192
- auto one_vector = vec2Tensor (one_vector_tmp, 1 , ctx);
191
+ auto one_vector = util::arrToTensor (one_vector_tmp, 1 , ctx);
193
192
auto x_sub_one = ctx->net ->addElementWise (*new_input_shape_tensor, *one_vector, nvinfer1::ElementWiseOperation::kSUB )
194
193
->getOutput (0 );
195
194
auto strides = ctx->net ->addElementWise (*one_vector, *x_sub_one, nvinfer1::ElementWiseOperation::kMIN )->getOutput (0 );
@@ -224,8 +223,8 @@ auto expand_registrations TRTORCH_UNUSED =
224
223
int32_t * tmp = new int32_t [expanded_size_rank];
225
224
for (int i = 0 ; i < expanded_size_rank; i++)
226
225
tmp[i] = expanded_size[i];
227
- auto expandedDimsTensor = vec2Tensor (tmp, expanded_size_rank, ctx);
228
- return add_expand_dynamic (ctx, n, in, expandedDimsTensor);
226
+ auto expandedDimsTensor = util::arrToTensor (tmp, expanded_size_rank, ctx);
227
+ return add_expand_dynamic (ctx, n, in, expandedDimsTensor, expandedDims, true );
229
228
} else {
230
229
return add_expand (ctx, n, in, expandedDims);
231
230
}
@@ -239,7 +238,8 @@ auto expand_registrations TRTORCH_UNUSED =
239
238
auto targetDims = targetTensor->getDimensions ();
240
239
LOG_DEBUG (" (expand_as layer) Expand input from " << input_dims << " to " << targetDims);
241
240
if (ctx->input_is_dynamic ) {
242
- return add_expand_dynamic (ctx, n, in, ctx->net ->addShape (*targetTensor)->getOutput (0 ));
241
+ return add_expand_dynamic (
242
+ ctx, n, in, ctx->net ->addShape (*targetTensor)->getOutput (0 ), targetDims, false );
243
243
} else {
244
244
return add_expand (ctx, n, in, targetDims);
245
245
}
0 commit comments