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 20 /*! 21 * \file tvm/relay/qnn/attrs.h 22 * \brief Auxiliary attributes for qnn operators. 23 */ 24 #ifndef TVM_RELAY_QNN_ATTRS_H_ 25 #define TVM_RELAY_QNN_ATTRS_H_ 26 27 #include <tvm/attrs.h> 28 #include <string> 29 30 namespace tvm { 31 namespace relay { 32 namespace qnn { 33 34 /*! \brief Attribute for requantize operator */ 35 struct RequantizeAttrs : public tvm::AttrsNode<RequantizeAttrs> { 36 double input_scale; 37 int32_t input_zero_point; 38 double output_scale; 39 int32_t output_zero_point; 40 std::string rounding; 41 DataType out_dtype; 42 43 TVM_DECLARE_ATTRS(RequantizeAttrs, "relay.attrs.RequantizeAttrs") { 44 TVM_ATTR_FIELD(input_scale) 45 .describe("The scale of the input tensor."); 46 TVM_ATTR_FIELD(input_zero_point) 47 .describe("The zero point of the input tensor."); 48 TVM_ATTR_FIELD(output_scale) 49 .describe("The scale of the output tensor."); 50 TVM_ATTR_FIELD(output_zero_point) 51 .describe("The zero point of the output tensor."); 52 TVM_ATTR_FIELD(rounding).set_default("UPWARD") 53 .describe("Defines the rounding direction when the value is midway between" 54 "two representable values. There are two supported modes - UPWARD" 55 "or TONEAREST. Both modes behave exactly same except at the" 56 "midpoints between the two representable values. At the midpoint," 57 "UPWARD rounds towards positive infinity (for example -1.5 will be" 58 "rounded to -1). TONEAREST is the standard rounding where the" 59 "value is rounded away from zero at midpoints (for example, -1.5" 60 "rounds to -2). More context can be found at following gblic manual" 61 "https://www.gnu.org/software/libc/manual/html_node/Rounding.html."); 62 TVM_ATTR_FIELD(out_dtype) 63 .set_default(NullValue<DataType>()) 64 .describe("Output data type, set to explicit type under mixed precision setting"); 65 } 66 }; 67 68 /*! \brief Attribute for quantize operator */ 69 struct QuantizeAttrs : public tvm::AttrsNode<QuantizeAttrs> { 70 int32_t output_zero_point; 71 double output_scale; 72 DataType out_dtype; 73 74 TVM_DECLARE_ATTRS(QuantizeAttrs, "relay.attrs.QuantizeAttrs") { 75 TVM_ATTR_FIELD(out_dtype) 76 .describe("Output data type, can be one of [int8 or uint8]."); 77 TVM_ATTR_FIELD(output_zero_point) 78 .describe("The zero_point for the activation of this op."); 79 TVM_ATTR_FIELD(output_scale) 80 .describe("The scale for the activation of this op."); 81 } 82 }; 83 84 /*! \brief Attribute for dequantize operator */ 85 struct DequantizeAttrs : public tvm::AttrsNode<DequantizeAttrs> { 86 int32_t input_zero_point; 87 double input_scale; 88 89 TVM_DECLARE_ATTRS(DequantizeAttrs, "relay.attrs.DequantizeAttrs") { 90 TVM_ATTR_FIELD(input_zero_point) 91 .describe("The zero_point for the input tensor of this op."); 92 TVM_ATTR_FIELD(input_scale) 93 .describe("The scale for the input tensor of this op."); 94 } 95 }; 96 97 /*! \brief Attributes used in QNN concatenate operator */ 98 struct QnnConcatenateAttrs : public tvm::AttrsNode<QnnConcatenateAttrs> { 99 Array<tvm::Expr> input_scales; 100 Array<tvm::Expr> input_zero_points; 101 double output_scale; 102 int32_t output_zero_point; 103 int axis; 104 105 TVM_DECLARE_ATTRS(QnnConcatenateAttrs, "relay.attrs.QnnConcatenateAttrs") { 106 TVM_ATTR_FIELD(input_scales) 107 .describe("The list of scales of input quantized tensors."); 108 TVM_ATTR_FIELD(input_zero_points) 109 .describe("The list of zero points of input quantized tensors."); 110 TVM_ATTR_FIELD(output_zero_point) 111 .describe("The zero_point for the output tensor."); 112 TVM_ATTR_FIELD(output_scale) 113 .describe("The scale for the output tensor."); 114 TVM_ATTR_FIELD(axis) 115 .describe("The axis at which the input arrays are concatenated." 116 "Should lie in range `[-ndim, ndim)`.") 117 .set_default(0); 118 } 119 }; // struct QnnConcatenateAttrs 120 121 /*! \brief Attribute for QNN Conv2d operator */ 122 struct QnnConv2DAttrs : public tvm::AttrsNode<QnnConv2DAttrs> { 123 // Traditional conv2d attributes. 124 Array<IndexExpr> strides; 125 Array<IndexExpr> padding; 126 Array<IndexExpr> dilation; 127 int groups; 128 IndexExpr channels; 129 Array<IndexExpr> kernel_size; 130 std::string data_layout; 131 std::string kernel_layout; 132 std::string out_layout; 133 DataType out_dtype; 134 135 // Quantization related attributes. 136 int32_t input_zero_point; 137 int32_t kernel_zero_point; 138 // The input tensor scale and kernel tensor scales are stored 139 // for easy access to this information. 140 double input_scale; 141 double kernel_scale; 142 143 TVM_DECLARE_ATTRS(QnnConv2DAttrs, "relay.attrs.QnnConv2DAttrs") { 144 TVM_ATTR_FIELD(strides).set_default(Array<IndexExpr>({1, 1})) 145 .describe("Specifies the strides of the convolution."); 146 TVM_ATTR_FIELD(padding).set_default(Array<IndexExpr>({0, 0})) 147 .describe("If padding is non-zero, then the input is implicitly zero-padded" 148 "on both sides for padding number of points"); 149 TVM_ATTR_FIELD(dilation).set_default(Array<IndexExpr>({1, 1})) 150 .describe("Specifies the dilation rate to use for dilated convolution."); 151 TVM_ATTR_FIELD(groups).set_default(1) 152 .describe("Controls the connections between inputs and outputs." 153 "At groups=1, all inputs are convolved to all outputs." 154 "At groups=2, the operation becomes equivalent to having two convolution" 155 "layers side by side, each seeing half the input channels, and producing" 156 "half the output channels, and both subsequently concatenated."); 157 TVM_ATTR_FIELD(channels) 158 .describe("The number of output channels in the convolution." 159 " If it is not set, inferred by shape of the weight.") 160 .set_default(NullValue<IndexExpr>()); 161 TVM_ATTR_FIELD(kernel_size) 162 .describe("Specifies the dimensions of the convolution window.") 163 .set_default(NullValue<Array<IndexExpr> >()); 164 TVM_ATTR_FIELD(data_layout).set_default("NCHW") 165 .describe("Dimension ordering of input data. Can be 'NCHW', 'NHWC', etc." 166 "'N', 'C', 'H', 'W' stands for batch, channel, height, and width" 167 "dimensions respectively. Convolution is applied on the 'H' and" 168 "'W' dimensions."); 169 TVM_ATTR_FIELD(kernel_layout).set_default("OIHW") 170 .describe("Dimension ordering of weight. Can be 'OIHW', 'OIHW16o16i', etc." 171 "'O', 'I', 'H', 'W' stands for num_filter, input_channel, height, and width" 172 "dimensions respectively."); 173 TVM_ATTR_FIELD(out_layout).set_default("") 174 .describe("Dimension ordering of output. Can be 'NCHW', 'NHWC', etc." 175 "'N', 'C', 'H', 'W' stands for batch, channel, height, and width" 176 "dimensions respectively. Default to be same as input layout."); 177 TVM_ATTR_FIELD(out_dtype) 178 .set_default(NullValue<DataType>()) 179 .describe("Output data type, set to explicit type under mixed precision setting"); 180 TVM_ATTR_FIELD(input_zero_point) 181 .describe("The zero point of the input tensor."); 182 TVM_ATTR_FIELD(kernel_zero_point) 183 .describe("The zero point of the kernel tensor."); 184 TVM_ATTR_FIELD(input_scale) 185 .describe("The quantization scale for the input tensor."); 186 TVM_ATTR_FIELD(kernel_scale) 187 .describe("The quantization scale for the weight tensor."); 188 } 189 }; 190 191 /*! \brief Attribute for QNN binary operator */ 192 struct QnnBinaryOpAttrs : public tvm::AttrsNode<QnnBinaryOpAttrs> { 193 int32_t lhs_zero_point; 194 double lhs_scale; 195 int32_t rhs_zero_point; 196 double rhs_scale; 197 int32_t output_zero_point; 198 double output_scale; 199 200 TVM_DECLARE_ATTRS(QnnBinaryOpAttrs, "relay.attrs.QnnBinaryOpAttrs") { 201 TVM_ATTR_FIELD(lhs_zero_point) 202 .describe("The zero_point for the lhs input tensor of this op."); 203 TVM_ATTR_FIELD(lhs_scale) 204 .describe("The scale for the lhs input tensor of this op."); 205 TVM_ATTR_FIELD(rhs_zero_point) 206 .describe("The zero_point for the rhs input tensor of this op."); 207 TVM_ATTR_FIELD(rhs_scale) 208 .describe("The scale for the rhs input tensor of this op."); 209 TVM_ATTR_FIELD(output_zero_point) 210 .describe("The zero_point for the activation of this op."); 211 TVM_ATTR_FIELD(output_scale) 212 .describe("The scale for the activation of this op."); 213 } 214 }; 215 216 /*! \brief Attributes for qnn dense operator */ 217 struct QnnDenseAttrs : public tvm::AttrsNode<QnnDenseAttrs> { 218 IndexExpr units; 219 DataType out_dtype; 220 // Quantization related attributes. 221 int32_t input_zero_point; 222 int32_t kernel_zero_point; 223 double input_scale; 224 double kernel_scale; 225 226 TVM_DECLARE_ATTRS(QnnDenseAttrs, "relay.attrs.QnnDenseAttrs") { 227 TVM_ATTR_FIELD(units) 228 .describe("Number of hidden units of the dense transformation."); 229 TVM_ATTR_FIELD(out_dtype) 230 .describe("Output data type, set to explicit type under mixed precision setting"); 231 TVM_ATTR_FIELD(input_zero_point) 232 .describe("The zero point of the input tensor."); 233 TVM_ATTR_FIELD(kernel_zero_point) 234 .describe("The zero point of the kernel tensor."); 235 TVM_ATTR_FIELD(input_scale) 236 .describe("The input tensor scale."); 237 TVM_ATTR_FIELD(kernel_scale) 238 .describe("The kernel tensor scale."); 239 } 240 }; 241 242 } // namespace qnn 243 } // namespace relay 244 } // namespace tvm 245 #endif // TVM_RELAY_QNN_ATTRS_H_ 246