tvm
Loading...
Searching...
No Matches
pooling.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
24#ifndef TVM_TOPI_NN_POOLING_H_
25#define TVM_TOPI_NN_POOLING_H_
26
27#include <tvm/arith/analyzer.h>
29#include <tvm/topi/nn.h>
30#include <tvm/topi/reduction.h>
31#include <tvm/topi/tags.h>
32
33#include <algorithm>
34#include <string>
35#include <vector>
36
37namespace tvm {
38namespace topi {
39namespace nn {
40
41using namespace tvm::te;
42
44enum PoolType : int {
47};
48
50 const ffi::Array<PrimExpr>& kernel_size,
51 const ffi::Array<PrimExpr>& stride_size,
52 const ffi::Array<PrimExpr>& padding_size, PoolType pool_type,
53 bool ceil_mode, const size_t height_axis, const size_t width_axis,
54 bool count_include_pad) {
55 TVM_FFI_ICHECK(out_grad->shape.size() >= 2) << "Pooling grad output must >= 2-D (H, W)";
56 TVM_FFI_ICHECK(x->shape.size() >= 2) << "Pooling input must >= 2-D (H, W)";
57 TVM_FFI_ICHECK_EQ(kernel_size.size(), 2) << "Pooling kernel_size must have 2 elements";
58 TVM_FFI_ICHECK_EQ(stride_size.size(), 2) << "Pooling stride_size must have 2 elements";
59 TVM_FFI_ICHECK_EQ(padding_size.size(), 4) << "Pooling padding_size must have 4 elements";
60
61 auto kernel_height = kernel_size[0];
62 auto kernel_width = kernel_size[1];
63 auto stride_height = stride_size[0];
64 auto stride_width = stride_size[1];
65
66 auto height = x->shape[height_axis];
67 auto width = x->shape[width_axis];
68
69 auto pad_top = padding_size[0];
70 auto pad_left = padding_size[1];
71 auto pad_bottom = padding_size[2];
72 auto pad_right = padding_size[3];
73
74 if (ceil_mode) {
75 // Additional padding to ensure we do ceil instead of floor when
76 // dividing by stride.
79 }
80
81 ffi::Array<PrimExpr> pad_before(std::vector<PrimExpr>(x->shape.size(), 0));
84
85 ffi::Array<PrimExpr> pad_after(std::vector<PrimExpr>(x->shape.size(), 0));
89 auto out_height =
91 auto out_width =
93
96
97 ffi::Array<PrimExpr> data_shape = x->shape;
98 ffi::Array<PrimExpr> out_shape = data_shape;
101
106 const bool do_pad = ((padding_h0 && *padding_h0) || (padding_w0 && *padding_w0)) ||
108
109 if (pool_type == kMaxPool) {
110 ffi::Array<PrimExpr> ravel_shape{data_shape.begin(), data_shape.end()};
113
114 auto windowh =
116 auto windoww =
118
119 auto argmax = MakeArgmaxReducer();
120 auto pad_x =
121 do_pad ? pad(x, pad_before, pad_after, tvm::min_value(PrimType(x->dtype)), "pad_temp") : x;
122
124 out_shape,
125 [&](const ffi::Array<PrimVar>& inds) {
126 ffi::Array<PrimExpr> window_inds =
127 inds.Map([](const PrimVar& var) { return var.as_or_throw<PrimExpr>(); });
130 auto idx = detail::RavelIndex(window_inds, ravel_shape);
131 return argmax({idx, pad_x(window_inds)}, {dheight, dwidth}, nullptr);
132 },
133 "maxpool_grad_argmax", kCommReduceIdx);
134
135 auto mp_inds = mp_argmax[0];
136
137 return tvm::te::compute(
139 [&](const ffi::Array<PrimVar>& inds) {
140 ffi::Array<PrimExpr> pad_inds =
141 inds.Map([](const PrimVar& var) { return var.as_or_throw<PrimExpr>(); });
144 auto idx = detail::RavelIndex(pad_inds, ravel_shape);
145
146 ffi::Array<PrimExpr> out_idx =
147 inds.Map([](const PrimVar& var) { return var.as_or_throw<PrimExpr>(); });
150
157
158 return tvm::sum(
161 mp_inds(out_idx) == idx),
162 out_grad(out_idx), MakeConst(PrimType(x->dtype), 0)),
163 {windowh, windoww});
164 },
165 "T_pool_grad", "pool_grad_max");
166 } else if (pool_type == kAvgPool) {
167 auto windowh =
169 auto windoww =
171 return tvm::te::compute(
173 [&](const ffi::Array<PrimVar>& inds) {
176
177 // output indices whose pooling windows cover current input element (can be out-of-bound)
178 ffi::Array<PrimExpr> out_idx =
179 inds.Map([](const PrimVar& var) { return var.as_or_throw<PrimExpr>(); });
182
189
190 PrimExpr divide_factor; // number of pooled elements
191 if (count_include_pad) {
193 } else {
196
199 h_start = max(h_start, IntImm(h_start.ty(), 0));
200 w_start = max(w_start, IntImm(w_start.ty(), 0));
201 divide_factor = max((h_end - h_start) * (w_end - w_start), IntImm(h_end.ty(), 1));
202 }
203 return tvm::sum(
209 MakeConst(PrimType(out_grad->dtype), 0)),
210 {windowh, windoww});
211 },
212 "T_pool_grad", "pool_grad_avg");
213 } else {
214 LOG(ERROR) << "Unrecognized pool_type: " << pool_type;
215 return Tensor();
216 }
217}
218
230inline bool find_depth_height_width(const std::string& layout, int* depth_axis, int* height_axis,
231 int* width_axis) {
232 if (depth_axis) *depth_axis = -1;
233 if (height_axis) *height_axis = -1;
234 if (width_axis) *width_axis = -1;
235 int curr_idx = 0;
236 for (size_t i = 0; i < layout.size(); ++i) {
237 if ((layout[i] >= 'A' && layout[i] <= 'Z') || (layout[i] >= 'a' && layout[i] <= 'z')) {
238 if (layout[i] == 'D' && depth_axis) {
239 if (*depth_axis != -1) return false;
241 } else if (layout[i] == 'H' && height_axis) {
242 if (*height_axis != -1) return false;
244 } else if (layout[i] == 'W' && width_axis) {
245 if (*width_axis != -1) return false;
247 } else if (layout[i] == 'd' || layout[i] == 'h' || layout[i] == 'w') {
248 // do not support split on height, width or depth, e.g., NCHW16w
249 return false;
250 }
251 ++curr_idx;
252 }
253 }
254 if ((depth_axis && *depth_axis == -1) || (height_axis && *height_axis == -1) ||
255 (width_axis && *width_axis == -1))
256 return false;
257 return true;
258}
259
260inline bool find_height_width(const std::string& layout, int* height_axis, int* width_axis) {
261 return find_depth_height_width(layout, /*depth_axis=*/nullptr, height_axis, width_axis);
262}
263
264inline bool find_width(const std::string& layout, int* width_axis) {
265 return find_depth_height_width(layout, /*depth_axis=*/nullptr, /*height_axis=*/nullptr,
266 width_axis);
267}
268
299inline Tensor pool_grad(const Tensor& out_grad, const Tensor& x,
300 const ffi::Array<PrimExpr>& kernel_size,
301 const ffi::Array<PrimExpr>& stride_size,
302 const ffi::Array<PrimExpr>& padding_size, PoolType pool_type,
303 bool ceil_mode, const std::string& layout = "NCHW",
304 bool count_include_pad = true) {
305 int height_axis = -1, width_axis = -1;
307 << "Unsupported layout " << layout;
309 height_axis, width_axis, count_include_pad);
310}
311
313 return indexdiv(out_index * idim, odim);
314}
315
318 return tvm::prim::Select(indexmod((out_index + 1) * idim, odim) == 0, tmp, tmp + 1);
319}
320
331inline Tensor adaptive_pool_impl(const Tensor& x, const ffi::Array<PrimExpr>& output_size,
332 PoolType pool_type, const std::vector<int>& axes) {
333 const auto n_dim = output_size.size();
334 TVM_FFI_ICHECK_EQ(axes.size(), n_dim) << "The number of axes not equal to the in/out dimension";
335
336 ffi::Array<PrimExpr> data_shape = x->shape;
337 ffi::Array<PrimExpr> out_shape = data_shape;
338 ffi::Array<PrimExpr> in_size, out_size;
339 for (size_t i = 0; i < n_dim; ++i) {
340 in_size.push_back(data_shape[axes[i]]);
341 out_size.push_back(output_size[i]);
342 out_shape.Set(axes[i], out_size[i]);
343 }
344
345 auto get_iter_vars = [=](const ffi::Array<PrimVar>& output, bool reduce_indices) {
346 ffi::Array<PrimExpr> indices;
347 for (size_t i = 0; i < output.size(); ++i) indices.push_back(output[i]);
348 ffi::Array<tirx::IterVar> reduce_axes;
349 for (size_t i = 0; i < n_dim; ++i) {
350 auto i_start = start_index(output[axes[i]], out_size[i], in_size[i]);
351 auto i_end = end_index(output[axes[i]], out_size[i], in_size[i]);
352 auto rv_name = "rv" + std::to_string(i);
354 reduce_axes.push_back(rv_axis);
355 if (reduce_indices) {
356 indices.Set(axes[i], i_start + rv_axis);
357 }
358 }
359 return std::make_tuple(indices, reduce_axes);
360 };
361
362 ffi::Map<ffi::String, ffi::Any> attrs;
363 if (pool_type == kMaxPool) {
364 attrs.Set("schedule_rule", tvm::ffi::String("meta_schedule.adaptive_pool_max"));
365 return tvm::te::compute(
366 out_shape,
367 [&](const ffi::Array<PrimVar>& output) {
368 ffi::Array<PrimExpr> indices;
369 ffi::Array<tirx::IterVar> reduce_axes;
370 std::tie(indices, reduce_axes) = get_iter_vars(output, true);
371 return tvm::max(x(indices), reduce_axes); // NOLINT(*)
372 },
373 "adaptive_pool_max", "adaptive_pool_max", attrs);
374 } else if (pool_type == kAvgPool) {
375 attrs.Set("schedule_rule", tvm::ffi::String("meta_schedule.adaptive_pool_avg"));
377 out_shape,
378 [&](const ffi::Array<PrimVar>& output) {
379 ffi::Array<PrimExpr> indices;
380 ffi::Array<tirx::IterVar> reduce_axes;
381 std::tie(indices, reduce_axes) = get_iter_vars(output, true);
382 return tvm::sum(x(indices), reduce_axes);
383 },
384 "adaptive_pool_sum", "adaptive_pool_sum");
385
386 return tvm::te::compute(
387 out_shape,
388 [&](const ffi::Array<PrimVar>& output) {
389 ffi::Array<PrimExpr> indices;
390 ffi::Array<tirx::IterVar> reduce_axes;
391 std::tie(indices, reduce_axes) = get_iter_vars(output, false);
392
394 for (size_t i = 0; i < n_dim; ++i) {
395 divide_factor *= tvm::cast(PrimType::Int(32), reduce_axes[i]->dom->extent);
396 }
397
398 return div(pool_sum(indices), divide_factor);
399 },
400 "adaptive_pool_avg", kElementWise, attrs);
401 } else {
402 LOG(ERROR) << "Unrecognized pool_type: " << pool_type;
403 return x;
404 }
405}
406
433inline Tensor adaptive_pool(const Tensor& x, const ffi::Array<PrimExpr>& output_size,
434 PoolType pool_type, const std::string& layout = "NCHW") {
435 int height_axis = -1, width_axis = -1;
437 << "Unsupported layout " << layout;
438 return adaptive_pool_impl(x, output_size, pool_type, {height_axis, width_axis});
439}
440
449inline Tensor adaptive_pool3d(const Tensor& x, const ffi::Array<PrimExpr>& output_size,
450 PoolType pool_type, const std::string& layout = "NCDHW") {
451 int depth_axis = -1, height_axis = -1, width_axis = -1;
453 << "Unsupported layout " << layout;
455}
456
465inline Tensor adaptive_pool1d(const Tensor& x, const ffi::Array<PrimExpr>& output_size,
466 PoolType pool_type, const std::string& layout = "NCW") {
467 int width_axis = -1;
468 TVM_FFI_ICHECK(find_width(layout, &width_axis)) << "Unsupported layout " << layout;
469 return adaptive_pool_impl(x, output_size, pool_type, {width_axis});
470}
471
497inline Tensor global_pool(const Tensor& x, PoolType pool_type, const std::string& layout = "NCHW") {
498 return adaptive_pool(x, ffi::Array<PrimExpr>{1, 1}, pool_type, layout);
499}
500
517inline Tensor pool_impl_nd(const Tensor& x, const ffi::Array<PrimExpr>& kernel_size,
518 const ffi::Array<PrimExpr>& stride_size,
519 const ffi::Array<PrimExpr>& dilation_size,
520 const ffi::Array<PrimExpr>& padding_size, PoolType pool_type,
521 bool ceil_mode, const std::vector<int>& axis, bool count_include_pad) {
522 int k_size = kernel_size.size();
523 int x_size = x->shape.size();
525 << "Pooling stride_size must have same elements as kernel";
527 << "Pooling padding_size must has double elements of"
528 " kernel";
529 TVM_FFI_ICHECK_EQ(axis.size(), k_size) << "axis must have same elements as kernel";
530
531 ffi::Array<IterVar> daxis;
532 std::vector<PrimExpr> kernel(k_size);
533 std::vector<PrimExpr> stride(k_size);
534 std::vector<PrimExpr> dilation(k_size);
535 std::vector<PrimExpr> pad_head(k_size);
536 std::vector<PrimExpr> pad_tail(k_size);
537 std::vector<PrimExpr> offset(k_size, 0);
538 ffi::Array<PrimExpr> pad_before(std::vector<PrimExpr>(x_size, 0));
539 ffi::Array<PrimExpr> pad_after(std::vector<PrimExpr>(x_size, 0));
540 ffi::Array<PrimExpr> data_shape = x->shape;
541 ffi::Array<PrimExpr> out_shape = data_shape;
542
543 bool do_pad = false;
544 for (int i = 0; i < k_size; i++) {
545 int ii = axis[i];
546 kernel[i] = kernel_size[i];
547 stride[i] = stride_size[i];
548 dilation[i] = dilation_size[i];
551
552 if (ceil_mode) {
553 // The offset[i] is an additional padding to ensure we do ceil instead of floor when
554 // dividing by stride.
555 // In the case of ceil_mode=True and count_include_pad=True,
556 // in order to obtain the correct boundary,
557 // we also need to use the offset[i] to eliminate this extra padding.
558 offset[i] = stride[i] - 1;
559 pad_tail[i] += offset[i];
560 }
561
564 do_pad = do_pad || (padding0 && *padding0) || (padding1 && *padding1);
565
566 daxis.push_back(tvm::te::reduce_axis(Range(0, kernel[i]), "rv" + std::to_string(i)));
567
568 pad_before.Set(ii, pad_head[i]);
569 pad_after.Set(ii, pad_tail[i]);
570
572
574 data_shape[ii] - (kernel[i] - 1) * dilation[i] - 1 + pad_head[i] + pad_tail[i];
575 auto raw_out = indexdiv(numerator, stride[i]) + 1;
576 if (ceil_mode) {
577 // In the case of ceil_mode=True, we need to check if the last pooling window is valid.
578 // If not, we skip the last window as it would start in the bottom padded region,
579 // we need to minus 1 to get the correct output shape.
580 auto invalid_last = (raw_out - 1) * stride[i] >= data_shape[ii] + pad_head[i];
581 auto out_dim = analyzer->Simplify(if_then_else(invalid_last, raw_out - 1, raw_out));
582 out_shape.Set(ii, out_dim);
583 } else {
584 auto out_dim = analyzer->Simplify(raw_out);
585 out_shape.Set(ii, out_dim);
586 }
587 }
588
589 ffi::Map<ffi::String, ffi::Any> attrs;
590 if (pool_type == kMaxPool) {
591 auto temp =
592 do_pad ? pad(x, pad_before, pad_after, tvm::min_value(PrimType(x->dtype)), "pad_temp") : x;
593 attrs.Set("schedule_rule", tvm::ffi::String("meta_schedule.pool_max"));
594 return tvm::te::compute(
595 out_shape,
596 [&](const ffi::Array<PrimVar>& output) {
597 ffi::Array<PrimExpr> indices;
598 for (const PrimVar& var : output) indices.push_back(var);
599
600 for (int i = 0; i < k_size; i++) {
601 int ii = axis[i];
602 indices.Set(ii, output[ii] * stride[i] + daxis[i] * dilation[i]);
603 }
604 return tvm::max(temp(indices), daxis);
605 },
606 "pool_max", "pool_max", attrs);
607 } else if (pool_type == kAvgPool) {
608 attrs.Set("schedule_rule", tvm::ffi::String("meta_schedule.pool_avg"));
609 // Pad the inputs
610 auto temp = do_pad ? pad(x, pad_before, pad_after, 0, "pad_temp") : x;
611
612 // TVM compute for summing the pooling window.
614 out_shape,
615 [&](const ffi::Array<PrimVar>& output) {
616 ffi::Array<PrimExpr> indices;
617 for (const PrimVar& var : output) indices.push_back(var);
618
619 for (int i = 0; i < k_size; i++) {
620 int ii = axis[i];
621 indices.Set(ii, output[ii] * stride[i] + daxis[i] * dilation[i]);
622 }
623 return tvm::sum(temp(indices), daxis);
624 },
625 "pool_sum", "pool_sum");
626
627 // TVM compute for dividing the reduced window sum by kernel size.
628 return tvm::te::compute(
629 out_shape,
630 [&](const ffi::Array<PrimVar>& output) {
631 ffi::Array<PrimExpr> indices;
632 for (const PrimVar& var : output) indices.push_back(var);
633 if (count_include_pad) {
634 std::vector<PrimExpr> start(k_size);
635 std::vector<PrimExpr> end(k_size);
636 auto num_el = IntImm::Int32(1);
637 for (int i = 0; i < k_size; i++) {
638 int ii = axis[i];
639 start[i] = output[ii] * stride[i] - pad_head[i];
640 // When computing the output shape in ceil_mode,
641 // we have added the extra padding of offset[i],
642 // so now in order to calculate the correct boundary ,
643 // we need to substract the offset[i].
644 end[i] = start[i] + (kernel[i] - 1) * dilation[i];
645 end[i] = min(end[i], data_shape[ii] + pad_tail[i] - 1 - offset[i]);
646 num_el *= (end[i] - start[i]) / dilation[i] + 1;
647 }
648 return div(pool_sum(indices), num_el);
649 } else {
650 std::vector<PrimExpr> start(k_size);
651 std::vector<PrimExpr> end(k_size);
652 auto num_el = IntImm::Int32(1);
653 for (int i = 0; i < k_size; i++) {
654 int ii = axis[i];
655
656 // Let start and end contain the first and last index of our Tensor
657 // along the relevant dimension we use in our calculation.
658 // Assume indices -1, -2 represent the padding before (tail) and
659 // len(arr), len(arr) + 1 represent the padding after (head).
660 start[i] = output[ii] * stride[i] - pad_head[i];
661 end[i] = start[i] + (kernel[i] - 1) * dilation[i];
662
663 // if start[i] < 0, e.g. we start on a tail padded number this will be a positive
664 // number that represents the number of steps along the dilated kernel to reach a
665 // non-padded value. Otherwise this should be 0.
666 PrimExpr jumps_to_non_pad = (dilation[i] - 1 - start[i]) / dilation[i];
668
669 end[i] = min(end[i], data_shape[ii] - 1);
670 num_el *= (end[i] - (start[i] + dilation[i] * jumps_to_non_pad)) / dilation[i] + 1;
671 }
672
674 return div(pool_sum(indices), divide_factor);
675 }
676 },
677 "pool_avg", kElementWise, attrs);
678 } else {
679 LOG(ERROR) << "Unrecognized pool_type: " << pool_type;
680 return x;
681 }
682}
683
714inline Tensor pool1d(const Tensor& x, const ffi::Array<PrimExpr>& kernel_size,
715 const ffi::Array<PrimExpr>& stride_size,
716 const ffi::Array<PrimExpr>& dilation_size,
717 const ffi::Array<PrimExpr>& padding_size, PoolType pool_type, bool ceil_mode,
718 const std::string& layout = "NCW", bool count_include_pad = true) {
719 int width_axis = -1;
720 TVM_FFI_ICHECK(find_width(layout, &width_axis)) << "Unsupported layout " << layout;
721 std::vector<int> axis = {width_axis};
723 ceil_mode, axis, count_include_pad);
724}
725
756inline Tensor pool2d(const Tensor& x, const ffi::Array<PrimExpr>& kernel_size,
757 const ffi::Array<PrimExpr>& stride_size,
758 const ffi::Array<PrimExpr>& dilation_size,
759 const ffi::Array<PrimExpr>& padding_size, PoolType pool_type, bool ceil_mode,
760 const std::string& layout = "NCHW", bool count_include_pad = true) {
761 int height_axis = -1, width_axis = -1;
763 << "Unsupported layout " << layout;
764 std::vector<int> axis = {height_axis, width_axis};
766 ceil_mode, axis, count_include_pad);
767}
768
800inline Tensor pool3d(const Tensor& x, const ffi::Array<PrimExpr>& kernel_size,
801 const ffi::Array<PrimExpr>& stride_size,
802 const ffi::Array<PrimExpr>& dilation_size,
803 const ffi::Array<PrimExpr>& padding_size, PoolType pool_type, bool ceil_mode,
804 const std::string& layout = "NCDHW", bool count_include_pad = true) {
805 int depth_axis = -1, height_axis = -1, width_axis = -1;
807 << "Unsupported layout " << layout;
808 std::vector<int> axis = {depth_axis, height_axis, width_axis};
810 ceil_mode, axis, count_include_pad);
811}
812
813} // namespace nn
814} // namespace topi
815} // namespace tvm
816#endif // TVM_TOPI_NN_POOLING_H_
Algebra expression simplifications.
Managed reference class to IntImmNode.
Definition expr.h:504
static IntImm Int32(int64_t value, Span span=Span())
Construct a scalar int32 constant.
Definition expr.h:528
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:401
Definition base_expr.h:137
static PrimType Int(int bits, int lanes=1)
Construct a signed integer type with fixed lanes.
Range container
Definition expr.h:610
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Managed reference to AnalyzerObj.
Definition analyzer.h:931
Managed reference to AndNode.
Definition expr.h:438
Managed reference to SelectNode.
Definition expr.h:525
Tensor structure representing a possible input, or intermediate computation result.
Definition tensor.h:98
Checked scalar view over a VarNode.
Definition var.h:46
Tensor expression language DSL.
Definition extracted_task.h:33
PrimVar var(std::string name_hint, PrimType t=PrimType::Int(32))
Construct a new Var expression.
IterVar reduce_axis(Range dom, std::string name="rv")
Create a new IterVar for reduction operations.
Tensor compute(ffi::Array< PrimExpr > shape, FCompute fcompute, std::string name="tensor", std::string tag="", ffi::Map< ffi::String, ffi::Any > attrs={})
Construct a new tensor by computing over shape, using the computation rule: result_tensor[axis] = fco...
const Op & max()
const int64_t * as_const_int(const PrimExpr &x)
Get x as constant int expression.
Definition op.h:840
const Op & min()
PrimExpr MakeConst(PrimType dtype, ValueType value, Span span=Span())
Make a const value with certain data type.
Definition op.h:1002
Tensor adaptive_pool3d(const Tensor &x, const ffi::Array< PrimExpr > &output_size, PoolType pool_type, const std::string &layout="NCDHW")
Adaptively perform pooling on three dimensional data. See the two dimensional version above for detai...
Definition pooling.h:449
Tensor adaptive_pool(const Tensor &x, const ffi::Array< PrimExpr > &output_size, PoolType pool_type, const std::string &layout="NCHW")
Adaptively perform pooling on height and width dimension of data. The pooling kernel and stride sizes...
Definition pooling.h:433
PoolType
Pooling type.
Definition pooling.h:44
@ kAvgPool
Definition pooling.h:45
@ kMaxPool
Definition pooling.h:46
PrimExpr start_index(const PrimVar &out_index, const PrimExpr &odim, const PrimExpr &idim)
Definition pooling.h:312
Tensor adaptive_pool1d(const Tensor &x, const ffi::Array< PrimExpr > &output_size, PoolType pool_type, const std::string &layout="NCW")
Adaptively perform pooling on one dimensional data. See the two dimensional version above for details...
Definition pooling.h:465
Tensor pool3d(const Tensor &x, const ffi::Array< PrimExpr > &kernel_size, const ffi::Array< PrimExpr > &stride_size, const ffi::Array< PrimExpr > &dilation_size, const ffi::Array< PrimExpr > &padding_size, PoolType pool_type, bool ceil_mode, const std::string &layout="NCDHW", bool count_include_pad=true)
Perform pooling on depth, height and width dimension of data. It decides the depth,...
Definition pooling.h:800
Tensor pool2d(const Tensor &x, const ffi::Array< PrimExpr > &kernel_size, const ffi::Array< PrimExpr > &stride_size, const ffi::Array< PrimExpr > &dilation_size, const ffi::Array< PrimExpr > &padding_size, PoolType pool_type, bool ceil_mode, const std::string &layout="NCHW", bool count_include_pad=true)
Perform pooling on height and width dimension of data. It decides the height and width dimension acco...
Definition pooling.h:756
Tensor pool_grad_impl(const Tensor &out_grad, const Tensor &x, const ffi::Array< PrimExpr > &kernel_size, const ffi::Array< PrimExpr > &stride_size, const ffi::Array< PrimExpr > &padding_size, PoolType pool_type, bool ceil_mode, const size_t height_axis, const size_t width_axis, bool count_include_pad)
Definition pooling.h:49
Tensor pool_grad(const Tensor &out_grad, const Tensor &x, const ffi::Array< PrimExpr > &kernel_size, const ffi::Array< PrimExpr > &stride_size, const ffi::Array< PrimExpr > &padding_size, PoolType pool_type, bool ceil_mode, const std::string &layout="NCHW", bool count_include_pad=true)
Calculate gradient of pooling on height and width dimension of data. It decides the height and width ...
Definition pooling.h:299
bool find_depth_height_width(const std::string &layout, int *depth_axis, int *height_axis, int *width_axis)
Find index of Depth, Height or Width dimension in a layout string.
Definition pooling.h:230
bool find_width(const std::string &layout, int *width_axis)
Definition pooling.h:264
Tensor pool_impl_nd(const Tensor &x, const ffi::Array< PrimExpr > &kernel_size, const ffi::Array< PrimExpr > &stride_size, const ffi::Array< PrimExpr > &dilation_size, const ffi::Array< PrimExpr > &padding_size, PoolType pool_type, bool ceil_mode, const std::vector< int > &axis, bool count_include_pad)
Perform pooling on N-dimension of data.
Definition pooling.h:517
PrimExpr end_index(const PrimVar &out_index, const PrimExpr &odim, const PrimExpr &idim)
Definition pooling.h:316
bool find_height_width(const std::string &layout, int *height_axis, int *width_axis)
Definition pooling.h:260
Tensor global_pool(const Tensor &x, PoolType pool_type, const std::string &layout="NCHW")
Perform global pooling on height and width dimension of data. It decides the height and width dimensi...
Definition pooling.h:497
Tensor adaptive_pool_impl(const Tensor &x, const ffi::Array< PrimExpr > &output_size, PoolType pool_type, const std::vector< int > &axes)
Perform adaptive pooling on N dimensional data.
Definition pooling.h:331
Tensor pool1d(const Tensor &x, const ffi::Array< PrimExpr > &kernel_size, const ffi::Array< PrimExpr > &stride_size, const ffi::Array< PrimExpr > &dilation_size, const ffi::Array< PrimExpr > &padding_size, PoolType pool_type, bool ceil_mode, const std::string &layout="NCW", bool count_include_pad=true)
Perform pooling on the width dimension of data. Width axis is determined by the layout string in whic...
Definition pooling.h:714
constexpr auto kElementWise
Definition tags.h:32
FCommReduce MakeArgmaxReducer(bool select_last_index=false)
Definition reduction.h:519
tvm::te::Tensor pad(const tvm::te::Tensor &t, const tvm::ffi::Array< tvm::PrimExpr > &pad_before, tvm::ffi::Array< tvm::PrimExpr > pad_after=tvm::ffi::Array< tvm::PrimExpr >(), PrimExpr pad_value=PrimExpr(), std::string name="T_pad", std::string tag=kElementWise, std::string pad_mode="constant", const ffi::Array< PrimExpr > *dyn_output_shape=nullptr)
Creates an operation that performs padding.
Definition nn.h:156
constexpr auto kCommReduceIdx
Definition tags.h:35
Tensor argmax(const Tensor &data, const ffi::Optional< ffi::Array< int64_t > > &axis, bool keepdims=false, bool atleast1d=false, bool select_last_index=false)
Creates an operation that finds the indices of the maximum values over a given axis.
Definition reduction.h:573
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
PrimExpr div(PrimExpr a, PrimExpr b, Span span=Span())
compute division in C semantics.
PrimExpr if_then_else(PrimExpr cond, PrimExpr true_value, PrimExpr false_value, Span span=Span())
Conditional expression.
PrimExpr cast(PrimType t, PrimExpr value, Span span=Span())
cast value to type.
PrimExpr min_value(PrimType dtype, Span span=Span())
PrimExpr indexdiv(PrimExpr a, PrimExpr b, Span span=Span())
compute floor(a / b) where a and b are non-negative.
PrimExpr sum(PrimExpr source, ffi::Array< tirx::IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
sum of source expression over axis
PrimExpr indexmod(PrimExpr a, PrimExpr b, Span span=Span())
compute the remainder floor(a / b) where a and b are non-negative.
Padding helpers.
Reduction op constructors.
Tag definitions.
NN op constructions.