input: 
  from typing import Tuple
  import tensorflow as tf
  
  @tf.function
  def decode_libsvm(input: tf.Tensor, num_features: int, dtype: tf.DType = tf.float32, label_dtype: tf.DType = tf.int64, name: str = None) -> Tuple[tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor]:
      """ Convert LibSVM input to tensors. The output consists of a label and a feature tensor.
      The shape of the label tensor is the same as input and the shape of the feature tensor is
      `[input_shape, num_features]`.
      
      Args:
          input: A `Tensor` of type `string`. Each string is a record in the LibSVM format.
          num_features: An `int` that is `>= 1`. The number of features.
          dtype: An optional `tf.DType` from: `tf.float32, tf.float64, tf.int32, tf.int64`. Defaults to `tf.float32`.
          label_dtype: An optional `tf.DType` from: `tf.float32, tf.float64, tf.int32, tf.int64`. Defaults to `tf.int64`.
          name: A name for the operation (optional).
          
      Returns:
          A tuple of `Tensor` objects `(label, feature_indices, feature_values, feature_shape)`.
          label: A `Tensor` of type `label_dtype`. A tensor of the same shape as input.
          feature_indices: A `Tensor` of type `int64`. A 2-D int64 tensor of dense_shape [N, ndims].
          feature_values: A `Tensor` of type `dtype`. A 1-D tensor of any type and dense_shape [N].
          feature_shape: A `Tensor` of type `int64`. A 1-D int64 tensor of dense_shape [ndims].
          
      >>> decode_libsvm(tf.constant(["1 1:1 2:2", "2 1:2 2:1"]), 2, tf.float32, tf.int32)
      (<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 2], dtype=int32)>,
      <tf.Tensor: shape=(4, 2), dtype=int64, numpy=
      array([[0, 1],
             [0, 2],
             [1, 1],
             [1, 2]])>,
      <tf.Tensor: shape=(4,), dtype=float32, numpy=array([1., 2., 2., 1.], dtype=float32)>,
      <tf.Tensor: shape=(2,), dtype=int64, numpy=array([2, 2, 3, 3])>)
      """
  
output:     
      def parse_libsvm_line(line):
          parts = tf.strings.split(line, ' ')
          label = tf.strings.to_number(parts[0], out_type=label_dtype)
          indices = []
          values = []
          for part in parts[1:]:
              index, value = tf.strings.split(part, ':')
              indices.append(tf.strings.to_number(index, out_type=tf.int64))
              values.append(tf.strings.to_number(value, out_type=dtype))
          return label, indices, values
  
      labels, indices_list, values_list = tf.map_fn(
          parse_libsvm_line,
          input,
          fn_output_signature=(label_dtype, tf.TensorSpec(shape=[None], dtype=tf.int64), tf.TensorSpec(shape=[None], dtype=dtype))
      )
  
      feature_indices = tf.RaggedTensor.from_row_splits(
          tf.concat(indices_list, axis=0),
          tf.concat([[0], tf.cumsum(tf.map_fn(lambda x: tf.size(x), indices_list, fn_output_signature=tf.int64))], axis=0)
      ).to_tensor(default_value=0, shape=[None, num_features])
  
      feature_values = tf.concat(values_list, axis=0)
  
      feature_shape = tf.shape(feature_indices, out_type=tf.int64)
  
      return labels, feature_indices, feature_values, feature_shape
  