siju-samuel commented on a change in pull request #5447:
URL: https://github.com/apache/incubator-tvm/pull/5447#discussion_r415997917



##########
File path: python/tvm/relay/frontend/tflite.py
##########
@@ -2075,6 +2077,29 @@ def convert_space_to_depth(self, op):
 
         return out
 
+    def convert_sparse_to_dense(self, op):
+        """Convert TFLite SPARSE_TO_DENSE"""
+        try:
+            from tflite.Operator import Operator
+        except ImportError:
+            raise ImportError("The tflite package must be installed")
+
+        assert isinstance(op, Operator)

Review comment:
       This code can be removed., its already checked in `convert_op_to_relay`

##########
File path: python/tvm/relay/op/transform.py
##########
@@ -884,3 +884,29 @@ def unravel_index(indices, shape):
     """
 
     return _make.unravel_index(indices, shape)
+
+def sparse_to_dense(sparse_indices, sparse_values, default_value, 
output_shape):
+    """Converts a sparse representation into a dense tensor.
+       Example::
+       -   sparse_to_dense([[0, 0], [1, 1]], [3, 3], 0, [2, 2]) = [[3, 0], [0, 
3]]
+
+       Parameters
+       ----------
+       sparse_indices : tvm.te.Tensor
+           A 0-D, 1-D, or 2-D tensor of type `int32` or `int64`.
+           `sparse_indices[i]` contains the complete index where 
`sparse_values[i]` will be placed.
+       sparse_values : tvm.te.Tensor
+           A 0-D or 1-D tensor.
+           Values corresponding to each row of sparse_indices,
+           or a scalar value to be used for all sparse indices.
+       default_value : tvm.te.Tensor

Review comment:
       type shoube be `relay.Expr` here

##########
File path: tests/python/relay/test_op_level3.py
##########
@@ -780,4 +826,5 @@ def verify_unravel_index(indices, shape, dtype):
     test_gather_nd()
     test_isfinite()
     test_isinf()
-    test_unravel_index()
\ No newline at end of file
+    test_unravel_index()
+    test_sparse_to_dense()

Review comment:
       Final newline missing

##########
File path: src/relay/op/tensor/transform.cc
##########
@@ -2732,5 +2732,87 @@ Example::
 .set_attr<FTVMCompute>("FTVMCompute", UnRavelIndexCompute)
 .set_attr<TOpPattern>("TOpPattern", kInjective);
 
+// sparse_to_dense
+TVM_REGISTER_NODE_TYPE(SparseToDenseAttrs);
+
+bool SparseToDenseRel(const Array<Type>& types,
+                int num_inputs,
+                const Attrs& attrs,
+                const TypeReporter& reporter) {

Review comment:
       Not aligned

##########
File path: src/relay/op/tensor/transform.cc
##########
@@ -2732,5 +2732,87 @@ Example::
 .set_attr<FTVMCompute>("FTVMCompute", UnRavelIndexCompute)
 .set_attr<TOpPattern>("TOpPattern", kInjective);
 
+// sparse_to_dense
+TVM_REGISTER_NODE_TYPE(SparseToDenseAttrs);
+
+bool SparseToDenseRel(const Array<Type>& types,
+                int num_inputs,
+                const Attrs& attrs,
+                const TypeReporter& reporter) {
+  CHECK_EQ(num_inputs, 3);
+  auto sparse_indices = types[0].as<TensorTypeNode>();
+  auto sparse_values  = types[1].as<TensorTypeNode>();
+  auto default_value  = types[2].as<TensorTypeNode>();
+  CHECK(sparse_indices != nullptr && sparse_values != nullptr && default_value 
!= nullptr);
+
+  CHECK(sparse_indices->dtype.is_int())
+      << "sparse_indices must be tensor of integers";
+
+  CHECK_LE(sparse_indices->shape.size(), 3)
+      << "sparse_indices must be a tensor of either 0D, 1D or 2D";
+
+  CHECK_LE(sparse_values->shape.size(), 2)
+      << "sparse_values must be a tensor of either 0D, 1D";
+
+  CHECK_EQ(default_value->shape.size(), 0)
+    << "default_value should be a scalar";
+
+  const auto* param = attrs.as<SparseToDenseAttrs>();
+  CHECK(param != nullptr);
+
+  Array<IndexExpr> oshape;
+  for (auto i : param->output_shape) {
+    oshape.push_back(i);
+  }
+  reporter->Assign(types[3], TensorType(oshape, sparse_values->dtype));
+  return true;
+}
+
+Array<te::Tensor> SparseToDenseCompute(const Attrs& attrs,
+                                 const Array<te::Tensor>& inputs,
+                                 const Type& out_type) {
+  CHECK_EQ(inputs.size(), 3);
+  const auto* param = attrs.as<SparseToDenseAttrs>();
+  CHECK(param != nullptr);
+  return {topi::sparse_to_dense(inputs[0], inputs[1], inputs[2], 
param->output_shape)};
+}
+
+TVM_REGISTER_GLOBAL("relay.op._make.sparse_to_dense")
+.set_body_typed([](Expr indices, Expr values, Expr default_value, 
Array<Integer> output_shape) {
+  auto attrs = make_object<SparseToDenseAttrs>();
+  attrs->output_shape = std::move(output_shape);
+  static const Op& op = Op::Get("sparse_to_dense");
+  return Call(op, {indices, values, default_value}, Attrs(attrs));
+});
+
+RELAY_REGISTER_OP("sparse_to_dense")
+.describe(R"code(A dense tensor from a sparse representation.
+
+- **sparse_indices**: A 0-D, 1-D, or 2-D tensor of integers containing 
location of sparse values
+
+- **sparse_values**: A 0-D or 1-D tensor containing the sparse values for the 
sparse indices.
+
+- **default_value**: A 0-D tensor containing the default value for the 
remaining locations. Defaults to 0.
+
+- **output_shape**: A list of integers. Shape of the dense output tensor.
+
+  Example::
+    -  sparse_to_dense([0, 0], [1, 2]], [1, 2], 0, [3, 4]) = [[1, 0, 0, 0], 
[0, 0, 2, 0], [0, 0, 0, 0]]
+
+)code" TVM_ADD_FILELINE)
+.set_num_inputs(3)
+.set_support_level(3)
+.set_attrs_type<SparseToDenseAttrs>()
+.add_argument("sparse_indices", "Tensor", "Contains sparse indices.")
+.add_argument("sparse_values",  "Tensor", "Contains values for sparse 
indices.")
+.add_argument("default_value",  "Tensor", "Value to set for non-sparse 
indices. Defaults to 0.")
+.add_argument("output_shape",  "List of integers", "Shape of the dense output 
tensor.")

Review comment:
       `output_shape` needed here?

##########
File path: topi/include/topi/transform.h
##########
@@ -1369,5 +1369,57 @@ inline Tensor one_hot(const Tensor& indices,
   }, name, tag);
 }
 
+/*!
+ * \brief Get a dense tensor.
+ * \param sparse_indices sparse_indices[i] contains the complete index where 
sparse_values[i] will be placed.
+ * \param sparse_values is a 0-D or 1-D tensor. Values corresponding to each 
row of sparse_indices
+ * \param default_value is a 0-D tensor. Defaults to zero.
+ * \param output_shape is the shape of the dense output tensor
+ * \param name output tensor name.
+ * \param tag output tensor tag.
+ * \return Tensor of output_shape.
+ */
+inline Tensor sparse_to_dense(const Tensor& sparse_indices,
+                    const Tensor& sparse_values,
+                    const Tensor& default_value,
+                    const Array<Integer>& output_shape,
+                    const std::string name = "T_sparse_to_dense",
+                    const std::string tag = kInjective) {

Review comment:
       Alignment

##########
File path: topi/python/topi/transform.py
##########
@@ -676,3 +676,30 @@ def unravel_index(indices, shape):
     """
 
     return cpp.unravel_index(indices, shape)
+
+def sparse_to_dense(sparse_indices, sparse_values, default_value, 
output_shape):
+    """Converts a sparse representation into a dense tensor.
+       Example::
+       -   sparse_to_dense([[0, 0], [1, 1]], [3, 3], 0, [2, 2]) = [[3, 0], [0, 
3]]
+
+       Parameters
+       ----------
+       sparse_indices : tvm.te.Tensor
+           A 0-D, 1-D, or 2-D tensor of type `int32` or `int64`.
+           `sparse_indices[i]` Contains the complete index where 
`sparse_values[i]` will be placed.
+       sparse_values : tvm.te.Tensor
+           A 0-D or 1-D tensor.
+           Values corresponding to each row of sparse_indices.
+           Or a scalar value to be used for all sparse indices.
+       default_value : tvm.te.Tensor
+          A 0-D tensor of the same type as sparse_values.
+          Value to set for indices not specified in sparse_indices.  Defaults 
to zero.
+       output_shape : list of integers

Review comment:
       Align with top

##########
File path: topi/include/topi/transform.h
##########
@@ -1369,5 +1369,57 @@ inline Tensor one_hot(const Tensor& indices,
   }, name, tag);
 }
 
+/*!
+ * \brief Get a dense tensor.
+ * \param sparse_indices sparse_indices[i] contains the complete index where 
sparse_values[i] will be placed.
+ * \param sparse_values is a 0-D or 1-D tensor. Values corresponding to each 
row of sparse_indices
+ * \param default_value is a 0-D tensor. Defaults to zero.
+ * \param output_shape is the shape of the dense output tensor
+ * \param name output tensor name.
+ * \param tag output tensor tag.
+ * \return Tensor of output_shape.
+ */
+inline Tensor sparse_to_dense(const Tensor& sparse_indices,
+                    const Tensor& sparse_values,
+                    const Tensor& default_value,
+                    const Array<Integer>& output_shape,
+                    const std::string name = "T_sparse_to_dense",
+                    const std::string tag = kInjective) {
+  CHECK(sparse_indices->dtype.is_int())
+    << "sparse_indices only accepts integer indices";

Review comment:
       >> sparse_indices only accepts integer values

##########
File path: topi/tests/python/test_topi_transform.py
##########
@@ -595,6 +595,41 @@ def check_device(device):
     for device in get_all_backend():
         check_device(device)
 
+def verify_sparse_to_dense(sparse_indices, sparse_values, default_value, 
output_shape, xpected):
+

Review comment:
       remove unwanted newlines




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to