class_docstr: Returns a tensor that has the same values as ``x`` with shape ``shape``.
  ``shape`` must have the same volume (number of elements) as ``x``.
  
  Parameters
  ----------
  x: tensor<*?, T> (Required)
      * A nd tensor or a scalar.
      * If ``x`` is fixed rank (and possibly contains symbolic dimension),
        shape may contain elements that are not positive integers (see below).
      * If ``x`` is variadic rank, shape can only contain positive integers.
  shape: tensor<[K], i32> (Required)
      * A 1D tensor, with elements from the followings:
        * Positive integers.
        * Symbols: All but one symbol in shape must be present in ``x.shape``.
          The new symbol that is not present in ``x.shape`` represent dimension
          such that the total size remains constant. Symbol is illegal
          if ``x`` is variadic rank.
        * -1: ``-1`` introduces a new symbol (see Symbols). Therefore, ``-1`` is
          allowed if all symbols in shape appear in ``x.shape``. ``-1`` is illegal
          if ``x`` is variadic rank.
        * 0: If ``K == rank(x)`` then ``0`` means inheriting from the corresponding
          dimension in ``x.shape``. ``0`` is illegal if ``x`` is variadic rank.
  
  Returns
  -------
  tensor<*?, T>
      * Tensor with shape determined by the input shape.
  
  Attributes
  ----------
  T: fp32
code: def enforce_volumetric_constraint(left_volume, inshape):
      left_symbols = set()
      if is_symbolic(left_volume):
          left_symbols = left_volume.free_symbols
      # Generally, we want to solve for right in terms of left. But this
      # is kinda annoying actually.
      shape = list(inshape)
  
      # Handling when reshape is given 0 instead of actual input
      # input tensor shape: [4, 3, 2], reshape:[0, -1], output tensor shape: [4, 6]
      if shape.count(-1) > 1:
          raise ValueError(
              "Reshape op supports only one dimension to be -1. Given {}".format(
                  shape.count(-1)
              )
          )
  
      infer_dim_index = shape.index(-1) if -1 in shape else None
      right_volume = 1
      for i in shape:
          if i != -1:
              right_volume = right_volume * i
  
      if infer_dim_index:
          shape[infer_dim_index] = left_volume // right_volume
  
      if not is_symbolic(right_volume):
          return shape
  
      constraints = [left_volume - right_volume]
      solve_for = [s for s in shape if is_symbolic(s)]
  
      for rightsym in solve_for:
          sol = sm.solve(constraints, [rightsym], dict=True)
          if not isinstance(sol, list):
              sol = [sol]
          # look for an acceptable solution
          for s in sol:
              if 0 in s.values():
                  continue
              for i in range(len(shape)):
                  if shape[i] in s:
                      v = s[shape[i]]
                      if len(v.free_symbols - left_symbols) > 0:
                          continue
                      try:
                          shape[i] = int(v)
                      except:
                          shape[i] = v
      return shape
  
imports: import functools
  import sympy
  from coremltools.converters.mil.mil.types.symbolic import is_symbolic, isscalar, any_symbolic, any_variadic
  from coremltools.converters.mil.mil import get_new_symbol, get_new_variadic_symbol, VALUE, SYMBOL, types
  from ._op_reqs import *
label_desc: Use image node_id 5 for calling the reshape obj's underlying member method code with example usage: obj.enforce_volumetric_constraint(left_volume, inshape) and returns: shape, shape