class_docstr: A compile-time operation that returns a constant output value upon de-sparsification of its constant inputs.
  
  This operation represents unstructured sparsity and uses bit mask binary representation.
  If a bit is set, then the corresponding element in the output tensor is non-zero and the
  value is read from the ``nonzero_data`` attribute. Likewise, if the bit is not set,
  then the corresponding element in the output tensor is zero.
  
  Parameters
  ----------
  nonzero_data: const tensor<T, [D]> (Required)
  
  mask: const tensor<uint8, [M]> (Required)
  
  shape: const tensor<uint32, [K]> (Required)
  
      Notes
      -----
  * Any data is packed and read in a row-major order.
  * ``mask`` contains ``M`` bytes, where ``M = ceil( product(shape) / 8)``. That is, each bit
    field corresponds to one element in the output tensor.
  * ``D ==`` the total number of set bits in ``mask``.
  
  The bit fields are packed one byte at a time, starting with the least significant bit and
  moving up to the most significant bit.
  
  For example:
  
  .. sourcecode:: python
  
      shape = (5,) => M = 1 bytes
      
                 MSB                  LSB
                  |                    |
      mask    =  |x  x  x  0  1  1  0  0 |      <== packed elements
                 |--|--|--|i4|i3|i2|i1|i0|      <== tagged element ids
                 |      byte 0           |      <== tagged bytes
  
  
  Returns
  -------
  const tensor<T, [...]>
  
  Attributes
  ----------
  T: uint8, int8, fp16, fp32
class_docstr_tok: ["A","compile-time","operation","that","returns","a","constant","output","value","upon","de-sparsification","of","its","constant","inputs",".","This","operation","represents","unstructured","sparsity","and","uses","bit","mask","binary","representation",".","If","a","bit","is","set",",","then","the","corresponding","element","in","the","output","tensor","is","non-zero","and","the","value","is","read","from","the","``","nonzero_data","``","attribute",".","Likewise",",","if","the","bit","is","not","set",",","then","the","corresponding","element","in","the","output","tensor","is","zero",".","Parameters","--","--","--","--","--","nonzero_data",":","const","tensor","<","T",",","[","D","]",">","(","Required",")","mask",":","const","tensor","<","uint8",",","[","M","]",">","(","Required",")","shape",":","const","tensor","<","uint32",",","[","K","]",">","(","Required",")","Notes","--","--","-","*","Any","data","is","packed","and","read","in","a","row-major","order",".","*","``","mask","``","contains","``","M","``","bytes",",","where","``","M","=","ceil","(","product","(","shape",")","\/","8",")","``",".","That","is",",","each","bit","field","corresponds","to","one","element","in","the","output","tensor",".","*","``","D","==","``","the","total","number","of","set","bits","in","``","mask","``",".","The","bit","fields","are","packed","one","byte","at","a","time",",","starting","with","the","least","significant","bit","and","moving","up","to","the","most","significant","bit",".","For","example",":","..","sourcecode",":",":","python","shape","=","(","5",",",")","=",">","M","=","1","bytes","MSB","LSB","|","|","mask","=","|x","x","x","0","1","1","0","0","|","<","==","packed","elements","|","--","|","--","|","--","|i4|i3|i2|i1|i0|","<","==","tagged","element","ids","|","byte","0","|","<","==","tagged","bytes","Returns","--","--","--","-","const","tensor","<","T",",","[","...","]",">","Attributes","--","--","--","--","--","T",":","uint8",",","int8",",","fp16",",","fp32"]
code: def type_inference(self):
      def assert_is_vector(param, name):
          if param.rank != 1:
              raise ValueError(
                  "Parameter {} needs to have rank == 1".format(name)
              )
  
      assert_is_vector(self.nonzero_data, "nonzero_data")
      assert_is_vector(self.mask, "mask")
  
      if (
          sum(bin(x).count("1") for x in self.mask.val)
          != self.nonzero_data.shape[0]
      ):
          raise AssertionError(
              "Number of set bits in mask needs to be equal to number of elements in parameter nonzero_data"
          )
  
      output_size = np.prod(self.shape.val)
      if self.mask.shape[0] != np.ceil(output_size / 8.0):
          raise AssertionError(
              "Constraint Violated: M = ceil( product(shape) / 8) where M = mask.size"
          )
  
      bitarray = np.unpackbits(self.mask.val, bitorder="little")
      if any(
          bitarray[i] != 0 for i in range(output_size, len(bitarray))
      ):
          raise AssertionError(
              "Padded bits in mask should be unset or equals to zero"
          )
  
      dtype = self.nonzero_data.dtype
      shape = self.shape.val
      return types.tensor(dtype, shape)
  
imports: import numpy
  from coremltools.converters.mil.mil import types
  from coremltools.converters.mil.mil.input_type import InputSpec, TensorInputType
  from coremltools.converters.mil.mil.operation import Operation
  from coremltools.converters.mil.mil.ops.defs._op_reqs import register_op
  from coremltools.converters.mil.mil.ops.defs._utils import restore_elements_from_packed_bits
  from coremltools.converters.mil.mil.ops.defs.iOS16 import _IOS16_TARGET
label_desc: Use image node_id 1 for calling the constexpr_sparse_to_dense obj's underlying member method code with example usage: obj.type_inference() and returns: types