[mlir][quant] Move comments to TableGen statements
authorrikhuijzer <rikhuijzer@pm.me>
Wed, 7 Jun 2023 16:04:19 +0000 (09:04 -0700)
committerJacques Pienaar <jpienaar@google.com>
Wed, 7 Jun 2023 17:08:56 +0000 (10:08 -0700)
The `quant` dialect documentation currently mostly empty (https://mlir.llvm.org/docs/Dialects/QuantDialect/).
This patch moves the comments to TableGen statements.
By looking at the generated `QuantDialect.md`, I've confirmed that each change in this patch will end up in the documentation.

The only thing that I wasn't able to document was the `UniformQuantizedType`.
I haven't found a way to document a `DialectType` since most appear to be private in other dialects; suggestions are welcome.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D151649

mlir/include/mlir/Dialect/Quant/QuantOps.td
mlir/include/mlir/Dialect/Quant/QuantOpsBase.td

index da0d1e9..7937265 100644 (file)
@@ -27,60 +27,76 @@ class quant_Op<string mnemonic, list<Trait> traits> :
 //===----------------------------------------------------------------------===//
 // Quantization casts
 //===----------------------------------------------------------------------===//
-// A QuantizeCast (qcast) represents a potential type shift from a quantizable
-// type to a quantized type.
-//
-// At runtime, a qcast will apply the transformation expressed by its
-// operand and result type. For flexibility during transformation, it is also
-// possible to have a qcast that performs no transformation (both its
-// operand and result type are quantizable).
-//
-// A qcast will typically originate from either:
-//   a) An expressed or implied constraint in the source dialect which signals
-//      that a certain level of quantization is possible or required.
-//   b) An inference made by a quantization algorithm indicating that a
-//      quantized representation may be acceptable.
-//
-// Especially early in transformation, it is common to have pairs of
-// qcast/dcast at points where a transition to a quantized type is
-// required. In addition, it is also common to have an identity qcast
-// (where the operand and result type are not quantized) at all points where
-// it is legal to use a quantized representation (but is not known to be
-// acceptable).
+
 def quant_QuantizeCastOp : quant_Op<"qcast", [Pure]> {
+  let summary = "convert a quantizable type to a quantized type";
+  let description = [{
+    A QuantizeCast `qcast` represents a potential type shift from a quantizable
+    type to a quantized type.
+
+    At runtime, a `qcast` will apply the transformation expressed by its
+    operand and result type. For flexibility during transformation, it is also
+    possible to have a `qcast` that performs no transformation (both its
+    operand and result type are quantizable).
+
+    A `qcast` will typically originate from either:
+      a) An expressed or implied constraint in the source dialect which signals
+         that a certain level of quantization is possible or required.
+      b) An inference made by a quantization algorithm indicating that a
+         quantized representation may be acceptable.
+
+    Especially early in transformation, it is common to have pairs of
+    `qcast` and `dcast` at points where a transition to a quantized type is
+    required. In addition, it is also common to have an identity `qcast`
+    (where the operand and result type are not quantized) at all points where
+    it is legal to use a quantized representation (but is not known to be
+    acceptable).
+  }];
   let arguments = (ins quant_RealValueType:$arg);
-  let results = (outs quant_RealValueType);
+  let results = (outs quant_RealValueType:$res);
 }
 
-// A DequantizeCast op (dcast) represents the inverse of a qcast,
-// converting back from a quantized to quantizable (expressed) type.
-//
-// Like qcasts, a dcast is allowed to have both its operand and result
-// as non quantized types. This facilitates transformations and marks edges
-// where the computation must be carried out in the expressed type.
-//
-// Especially early in transformation, it is common to have dcasts on
-// all operands to ops that must operate with the expressed type (typically
-// math ops prior to lowering to target-specific, quantized kernels).
 def quant_DequantizeCastOp : quant_Op<"dcast", [Pure]> {
+  let summary = "convert back from a quantized to quantizable (expressed) type operation";
+  let description = [{
+    A DequantizeCast op `dcast` represents the inverse of a `qcast`,
+    converting back from a quantized to quantizable (expressed) type.
+
+    Like `qcast`s, a `dcast` is allowed to have both its operand and result
+    as non quantized types. This facilitates transformations and marks edges
+    where the computation must be carried out in the expressed type.
+
+    Especially early in transformation, it is common to have `dcast`s on
+    all operands to ops that must operate with the expressed type (typically
+    math ops prior to lowering to target-specific, quantized kernels).
+  }];
   let arguments = (ins quant_RealValueType:$arg);
-  let results = (outs quant_RealValueType);
+  let results = (outs quant_RealValueType:$res);
 }
 
-// A StorageCast (scast) represents a cast from or to a type based on the
-// storage type and a type based on a corresponding quantized type.
-//
-// This op exists to ensure type coherency for between parts of the computation
-// which are operating directly on an underlying storage type and those which
-// operate on quantized values.
-//
-// Examples from storage to quantized type:
-//   i8 -> !quant<"uniform[i8:f32]{1.0}">
-//   tensor<4xi8> -> tensor<4x!quant<"uniform[i8:f32]{1.0}">>
-//   vector<4xi8> -> vector<4x!quant<"uniform[i8:f32]{1.0}">>
 def quant_StorageCastOp : quant_Op<"scast", [Pure]> {
+  let summary = "cast from or to a type based on the storage type and the corresponding quantized type";
+  let description = [{
+    A StorageCast `scast` represents a cast from or to a type based on the
+    storage type and a type based on a corresponding quantized type.
+
+    This op exists to ensure type coherency for between parts of the computation
+    which are operating directly on an underlying storage type and those which
+    operate on quantized values.
+
+    Examples from storage to quantized type:
+    ```
+    i8 -> !quant<"uniform[i8:f32]{1.0}">
+    ```
+    ```
+    tensor<4xi8> -> tensor<4x!quant<"uniform[i8:f32]{1.0}">>
+    ```
+    ```
+    vector<4xi8> -> vector<4x!quant<"uniform[i8:f32]{1.0}">>
+    ```
+  }];
   let arguments = (ins quant_RealOrStorageValueType:$arg);
-  let results = (outs quant_RealOrStorageValueType);
+  let results = (outs quant_RealOrStorageValueType:$res);
   let hasFolder = 1;
 }
 
index 559ec9c..4167676 100644 (file)
@@ -59,8 +59,8 @@ def quant_StorageValueType :
 
 // Either a real valued or storage primitive or container type.
 def quant_RealOrStorageValueType :
-    Type<Or<[quant_RealValueType.predicate,
-                quant_StorageValueType.predicate]>>;
+    Type<Or<[quant_RealValueType.predicate, quant_StorageValueType.predicate]>,
+    "real valued or storage primitive or container type">;
 
 // An implementation of UniformQuantizedType.
 def quant_UniformQuantizedType :