|
21 | 21 | @converter_registry.register("pd_op.pool2d", trt_version="8.x") |
22 | 22 | def pool2d_converter(network, paddle_op, inputs): |
23 | 23 | input_tensor = inputs[0] |
24 | | - pooling_type = paddle_op.attrs().get("pooling_type", "max") |
25 | | - padding = paddle_op.attrs().get("paddings", [0, 0]) |
26 | | - stride = paddle_op.attrs().get("strides", [1, 1]) |
27 | | - ceil_mode = paddle_op.attrs().get("ceil_mode", False) |
28 | | - exclusive = paddle_op.attrs().get("exclusive") |
29 | | - adaptive = paddle_op.attrs().get("adaptive") |
30 | | - padding_algorithm = paddle_op.attrs().get("padding_algorithm") |
31 | 24 |
|
32 | | - input_shape = input_tensor.shape |
| 25 | + input_shape = paddle_op.operands()[0].source().shape |
| 26 | + input_dims = len(input_shape) |
| 27 | + |
| 28 | + global_pooling = paddle_op.attrs().get("global_pooling", False) |
| 29 | + pool_type = paddle_op.attrs().get("pooling_type") |
| 30 | + strides = paddle_op.attrs().get("strides") |
| 31 | + paddings = paddle_op.attrs().get("paddings") |
| 32 | + exclusive = paddle_op.attrs().get("exclusive", True) |
| 33 | + ceil_mode = paddle_op.attrs().get("ceil_mode", False) |
| 34 | + adaptive = paddle_op.attrs().get("adaptive", False) |
| 35 | + padding_algorithm = paddle_op.attrs().get("padding_algorithm", "EXPLICIT") |
33 | 36 |
|
34 | | - # TODO attention for these codes |
35 | 37 | if not paddle_op.attrs().get("kernel_size") and len(inputs) == 2: |
36 | | - # the size of pool2d inputs is 2, means kernel size is the second input. |
37 | | - # kernel_size_tensor = inputs[1] |
38 | 38 | full_int_op = paddle_op.operands()[1].source().get_defining_op() |
39 | 39 | if full_int_op.name() == "pd_op.full_int_array": |
40 | 40 | kernel_size = full_int_op.attrs().get("value") |
41 | 41 | else: |
42 | 42 | raise Exception( |
43 | | - "the defining op of kernel size must be pd_op.full_int_array" |
| 43 | + "The defining op of kernel size must be pd_op.full_int_array" |
44 | 44 | ) |
45 | 45 | else: |
46 | 46 | kernel_size = paddle_op.attrs().get("kernel_size") |
47 | 47 |
|
48 | | - if len(stride) == 0 or stride[0] is None: |
49 | | - stride = kernel_size |
| 48 | + nv_pool_type = trt.PoolingType.MAX |
| 49 | + reduce_operation = trt.ReduceOperation.MAX |
| 50 | + if pool_type == "max": |
| 51 | + nv_pool_type = trt.PoolingType.MAX |
| 52 | + reduce_operation = trt.ReduceOperation.MAX |
| 53 | + elif pool_type == "avg": |
| 54 | + nv_pool_type = trt.PoolingType.AVERAGE |
| 55 | + reduce_operation = trt.ReduceOperation.AVG |
50 | 56 |
|
51 | | - if pooling_type == "max": |
52 | | - pooling_type = trt.PoolingType.MAX |
53 | | - elif pooling_type == "avg": |
54 | | - pooling_type = trt.PoolingType.AVERAGE |
55 | | - else: |
56 | | - raise ValueError(f"Unsupported pooling type: {pooling_type}") |
| 57 | + if global_pooling or adaptive: |
| 58 | + paddings = [0] * len(paddings) |
57 | 59 |
|
58 | 60 | if padding_algorithm == "VALID": |
59 | | - padding = [0, 0] |
60 | | - |
61 | | - if adaptive: |
62 | | - output_size = kernel_size |
63 | | - stride = tuple(input_shape[-2 + i] // output_size[i] for i in range(2)) |
64 | | - kernel_size = tuple( |
65 | | - input_shape[-2 + i] - (output_size[i] - 1) * stride[i] |
66 | | - for i in range(2) |
| 61 | + paddings = [0] * len(paddings) |
| 62 | + |
| 63 | + nv_paddings = trt.DimsHW(paddings[0], paddings[1]) |
| 64 | + nv_ksize = trt.DimsHW(kernel_size[0], kernel_size[1]) |
| 65 | + nv_strides = trt.DimsHW(strides[0], strides[1]) |
| 66 | + |
| 67 | + layer = None |
| 68 | + g_pre_pad = trt.DimsHW(0, 0) |
| 69 | + g_post_pad = trt.DimsHW(0, 0) |
| 70 | + |
| 71 | + if ( |
| 72 | + input_shape[input_dims - 2] > 0 |
| 73 | + and input_shape[input_dims - 2] - kernel_size[0] + 2 * paddings[0] < 0 |
| 74 | + ): |
| 75 | + g_post_pad.h = strides[0] - 1 |
| 76 | + if ( |
| 77 | + input_shape[input_dims - 1] > 0 |
| 78 | + and input_shape[input_dims - 1] - kernel_size[1] + 2 * paddings[1] < 0 |
| 79 | + ): |
| 80 | + g_post_pad.w = strides[1] - 1 |
| 81 | + |
| 82 | + real_paddings = paddings.copy() |
| 83 | + for i in range(2): |
| 84 | + copy_pad = paddings[i] |
| 85 | + real_paddings.insert(2 * i + 1, copy_pad) |
| 86 | + |
| 87 | + if padding_algorithm == "SAME": |
| 88 | + for i in range(2): |
| 89 | + copy_pad = paddings[2 * i] |
| 90 | + paddings.insert(2 * i + 1, copy_pad) |
| 91 | + |
| 92 | + for i in range(2): |
| 93 | + out_size = (input_shape[2 + i] + strides[i] - 1) // strides[i] |
| 94 | + pad_sum = max( |
| 95 | + (out_size - 1) * strides[i] |
| 96 | + + kernel_size[i] |
| 97 | + - input_shape[2 + i], |
| 98 | + 0, |
| 99 | + ) |
| 100 | + pad_0 = pad_sum // 2 |
| 101 | + pad_1 = pad_sum - pad_0 |
| 102 | + paddings[2 * i] = pad_0 |
| 103 | + paddings[2 * i + 1] = pad_1 |
| 104 | + real_paddings = paddings.copy() |
| 105 | + |
| 106 | + paddings = [paddings[i] for i in range(len(paddings)) if i % 2 == 0] |
| 107 | + |
| 108 | + if padding_algorithm == "VALID": |
| 109 | + read_paddings = [0] * len(real_paddings) |
| 110 | + |
| 111 | + if not adaptive and not global_pooling and not ceil_mode: |
| 112 | + if padding_algorithm != "SAME" and ( |
| 113 | + (g_post_pad.h > 0 and input_shape[input_dims - 2] > 0) |
| 114 | + or (g_post_pad.w > 0 and input_shape[input_dims - 1] > 0) |
| 115 | + ): |
| 116 | + pad_layer = network.add_padding_nd( |
| 117 | + input=input_tensor, |
| 118 | + pre_padding=tuple(g_pre_pad), |
| 119 | + post_padding=tuple(g_post_pad), |
| 120 | + ) |
| 121 | + input_tensor = pad_layer.get_output(0) |
| 122 | + pooling_layer = network.add_pooling_nd( |
| 123 | + input=input_tensor, type=nv_pool_type, window_size=nv_ksize |
67 | 124 | ) |
| 125 | + pooling_layer.stride_nd = nv_strides |
| 126 | + pooling_layer.padding_nd = nv_paddings |
| 127 | + pooling_layer.average_count_excludes_padding = exclusive |
| 128 | + if padding_algorithm == "SAME": |
| 129 | + pooling_layer.padding_mode = trt.PaddingMode.SAME_UPPER |
68 | 130 |
|
69 | | - pool_layer = network.add_pooling_nd( |
70 | | - input_tensor, pooling_type, window_size=kernel_size |
| 131 | + layer = pooling_layer |
| 132 | + elif not adaptive and not global_pooling and ceil_mode: |
| 133 | + pooling_layer = network.add_pooling_nd( |
| 134 | + input=input_tensor, type=nv_pool_type, window_size=nv_ksize |
| 135 | + ) |
| 136 | + pooling_layer.stride_nd = nv_strides |
| 137 | + pooling_layer.padding_nd = nv_paddings |
| 138 | + pooling_layer.average_count_excludes_padding = exclusive |
| 139 | + if padding_algorithm == "SAME": |
| 140 | + pooling_layer.padding_mode = trt.PaddingMode.SAME_UPPER |
| 141 | + else: |
| 142 | + pooling_layer.padding_mode = trt.PaddingMode.EXPLICIT_ROUND_UP |
| 143 | + layer = pooling_layer |
| 144 | + elif global_pooling and not adaptive: |
| 145 | + reduce_axes = (1 << (input_dims - 2)) | (1 << (input_dims - 1)) |
| 146 | + reduce_layer = network.add_reduce( |
| 147 | + input=input_tensor, |
| 148 | + op=reduce_operation, |
| 149 | + axes=reduce_axes, |
| 150 | + keep_dims=True, |
71 | 151 | ) |
72 | | - pool_layer.stride_nd = stride |
73 | | - if pooling_type == "max": |
74 | | - pool_layer.padding_nd = padding |
| 152 | + layer = reduce_layer |
75 | 153 | else: |
76 | | - pool_layer = network.add_pooling( |
77 | | - input_tensor, pooling_type, window_size=kernel_size |
| 154 | + raise NotImplementedError( |
| 155 | + "The combination of attributes is not supported yet." |
78 | 156 | ) |
79 | | - pool_layer.stride = stride |
80 | | - pool_layer.padding = padding |
81 | | - if exclusive: |
82 | | - pool_layer.average_count_excludes_padding = True |
83 | | - else: |
84 | | - pool_layer.average_count_excludes_padding = False |
85 | | - if ceil_mode: |
86 | | - pool_layer.padding_mode = trt.PaddingMode.EXPLICIT_ROUND_UP |
87 | 157 |
|
88 | | - return pool_layer.get_output(0) |
| 158 | + output_tensor = layer.get_output(0) |
| 159 | + return output_tensor |
0 commit comments