@@ -199,6 +199,131 @@ nvinfer1::ITensor* tensor_to_const(ConversionCtx* ctx, at::Tensor t, const std::
199
199
return out;
200
200
}
201
201
202
+ // clamp x to [lower_bound, upper_bound]
203
+ nvinfer1::ITensor* clamp (
204
+ ConversionCtx* ctx,
205
+ nvinfer1::ITensor* x,
206
+ nvinfer1::ITensor* lower_bound,
207
+ nvinfer1::ITensor* upper_bound,
208
+ std::string const & name) {
209
+
210
+ auto max_layer = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kMAX , x, lower_bound, " max layer for " + name);
211
+ TORCHTRT_CHECK (max_layer, " Unable to create max layer for clamp" );
212
+ LOG_DEBUG (ctx->logger , " Create " << max_layer->getName () << " for clamp" );
213
+ auto max_itensor = max_layer->getOutput (0 );
214
+
215
+ auto min_layer = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kMIN , max_itensor, upper_bound, " min layer for " + name);
216
+ TORCHTRT_CHECK (min_layer, " Unable to create min layer for clamp" );
217
+ LOG_DEBUG (ctx->logger , " Create " << min_layer->getName () << " for clamp" );
218
+ auto min_itensor = min_layer->getOutput (0 );
219
+ return min_itensor;
220
+ }
221
+
222
+ // clamp x to [0, input_dim]
223
+ nvinfer1::ITensor* clamp_to_input_dim (
224
+ ConversionCtx* ctx,
225
+ nvinfer1::ITensor* x,
226
+ nvinfer1::ITensor* input_dim,
227
+ int nbdims,
228
+ std::string const & name) {
229
+
230
+ auto zero = torch::zeros ({nbdims}).to (torch::kI32 );
231
+ auto zero_itensor = tensor_to_const (ctx, zero);
232
+ auto one = torch::ones ({nbdims}).to (torch::kI32 );
233
+ auto one_itensor = tensor_to_const (ctx, one);
234
+
235
+ auto upper_bound_layer = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kSUB , input_dim, one_itensor, " sub layer for " + name);
236
+ TORCHTRT_CHECK (upper_bound_layer, " Unable to create sub layer for clamp to inputDim" );
237
+ LOG_DEBUG (ctx->logger , " Create " << upper_bound_layer->getName () << " for clamp to inputDim" );
238
+ auto upper_bound = upper_bound_layer->getOutput (0 );
239
+
240
+ auto max_layer = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kMAX , x, zero_itensor, " max layer for " + name);
241
+ TORCHTRT_CHECK (max_layer, " Unable to create max_layer for clamp to inputDim" );
242
+ LOG_DEBUG (ctx->logger , " Create " << max_layer->getName () << " for clamp to inputDim" );
243
+ auto max_itensor = max_layer->getOutput (0 );
244
+
245
+ auto min_layer = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kMIN , max_itensor, upper_bound, " min layer for " + name);
246
+ TORCHTRT_CHECK (min_layer, " Unable to create min_layer for clamp to inputDim" );
247
+ LOG_DEBUG (ctx->logger , " Create " << min_layer->getName () << " for clamp to inputDim" );
248
+ auto min_itensor = min_layer->getOutput (0 );
249
+ return min_itensor;
250
+ }
251
+
252
+ // return indices < 0 ? inputDims + indices : indices
253
+ nvinfer1::ITensor* normalize_indices (
254
+ ConversionCtx* ctx,
255
+ nvinfer1::ITensor* input_dim,
256
+ nvinfer1::ITensor* indices,
257
+ int nbdims,
258
+ std::string const & name) {
259
+
260
+ auto zero = torch::zeros ({nbdims}).to (torch::kI32 );
261
+ auto neg = -torch::ones ({nbdims}).to (torch::kI32 );
262
+ auto zero_itensor = tensor_to_const (ctx, zero);
263
+ auto neg_itensor = tensor_to_const (ctx, neg);
264
+ // find the indices that = -1
265
+ auto signs = clamp (ctx, indices, neg_itensor, zero_itensor, " clamp layer for " + name);
266
+
267
+ // get the inputDim value where indices == -1, else 0
268
+ auto mul = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kPROD , signs, input_dim, " prod layer for " + name);
269
+ TORCHTRT_CHECK (mul, " Unable to create mul layer in normalize_indices" );
270
+ LOG_DEBUG (ctx->logger , " Create " << mul->getName () << " for normalize_indices" );
271
+ auto mul_itensor = mul->getOutput (0 );
272
+
273
+ // add the inputDim value to indices where indices == -1
274
+ auto sub = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kSUB , indices, mul_itensor, " sub layer for " + name);
275
+ TORCHTRT_CHECK (sub, " Unable to create sub layer in normalize_indices" );
276
+ LOG_DEBUG (ctx->logger , " Create " << sub->getName () << " for normalize_indices" );
277
+ auto sub_itensor = sub->getOutput (0 );
278
+ return sub_itensor;
279
+ }
280
+
281
+ std::vector<nvinfer1::ITensor*> normalize_start_and_end (
282
+ ConversionCtx* ctx,
283
+ nvinfer1::ITensor* in_shape,
284
+ nvinfer1::ITensor* in_start,
285
+ nvinfer1::ITensor* in_end,
286
+ int nbdims,
287
+ std::string const & name) {
288
+ auto start = normalize_indices (ctx, in_shape, in_start, nbdims, " normalize start of " + name);
289
+ auto out_start = clamp_to_input_dim (ctx, start, in_shape, nbdims, " clamp start to inputDim for " + name);
290
+ auto end = normalize_indices (ctx, in_shape, in_end, nbdims, " normalize end of " + name);
291
+ auto out_end = clamp_to_input_dim (ctx, end, in_shape, nbdims, " clamp end to inputDim for " + name);
292
+ std::vector<nvinfer1::ITensor*> outputs;
293
+ outputs.push_back (out_start);
294
+ outputs.push_back (out_end);
295
+ return outputs;
296
+ }
297
+
298
+ // size = (end - start) / stride + 1, where range is [start, end], end is included
299
+ nvinfer1::ITensor* get_slice_size (
300
+ ConversionCtx* ctx,
301
+ nvinfer1::ITensor* start,
302
+ nvinfer1::ITensor* end,
303
+ nvinfer1::ITensor* stride,
304
+ int nbdims,
305
+ std::string const & name) {
306
+ at::Tensor one_tensor = torch::ones ({nbdims}).to (torch::kI32 );
307
+ auto one_itensor = tensor_to_const (ctx, one_tensor);
308
+
309
+ auto sub_layer = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kSUB , end, start, " get_slice_size sub layer for " + name);
310
+ TORCHTRT_CHECK (sub_layer, " Unable to create sub layer in calculate_output_size" );
311
+ LOG_DEBUG (ctx->logger , " Create " << sub_layer->getName () << " for calculate_output_size" );
312
+ auto sub_itensor = sub_layer->getOutput (0 );
313
+
314
+ auto div_layer = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kDIV , sub_itensor, stride, " get_slice_size div layer for " + name);
315
+ TORCHTRT_CHECK (div_layer, " Unable to create div layer in calculate_output_size" );
316
+ LOG_DEBUG (ctx->logger , " Create " << div_layer->getName () << " for calculate_output_size" );
317
+ auto div_itensor = div_layer->getOutput (0 );
318
+
319
+ auto add_layer = add_elementwise (ctx, nvinfer1::ElementWiseOperation::kSUM , div_itensor, one_itensor, " get_slice_size sum layer for " + name);
320
+ TORCHTRT_CHECK (add_layer, " Unable to create add layer in calculate_output_size" );
321
+ LOG_DEBUG (ctx->logger , " Create " << add_layer->getName () << " for calculate_output_size" );
322
+ auto size_itensor = add_layer->getOutput (0 );
323
+
324
+ return size_itensor;
325
+ }
326
+
202
327
} // namespace converters
203
328
} // namespace conversion
204
329
} // namespace core
0 commit comments