class_docstr: Perform body repeatly while the condition cond is true.
  
  Parameters
  ----------
  _cond: Python function  (Required)
      * A Python function that takes ``loop_vars`` as positional arguments. The function must return a bool Var.
  
  _body: Python function  (Required)
      * A Python function that takes ``loop_vars`` as positional arguments. The function must return the same number of output vars as ``loop_var`` with the same types.
  
  loop_vars: Python tuple (Required)
      * Python tuple of ``Variables``.
  
  Returns
  -------
  Python tuple
      * Same type as ``loop_vars``
class_docstr_tok: ["Perform","body","repeatly","while","the","condition","cond","is","true",".","Parameters","--","--","--","--","--","_cond",":","Python","function","(","Required",")","*","A","Python","function","that","takes","``","loop_vars","``","as","positional","arguments",".","The","function","must","return","a","bool","Var",".","_body",":","Python","function","(","Required",")","*","A","Python","function","that","takes","``","loop_vars","``","as","positional","arguments",".","The","function","must","return","the","same","number","of","output","vars","as","``","loop_var","``","with","the","same","types",".","loop_vars",":","Python","tuple","(","Required",")","*","Python","tuple","of","``","Variables","``",".","Returns","--","--","--","-","Python","tuple","*","Same","type","as","``","loop_vars","``"]
code: def build_nested_blocks(self):
      # self.loop_vars is python tuple of Vars.
  
      # block_inputs Var are not produced by any op.
      # We assume block_inputs have the same types as self.loop_var. If not
      # (e.g., when certain dimensions change shape during iterate), we'd
      # adjust later.
  
      # We assume that sym_val is unchanging across the block iterate. If it
      # changes, we rebuild the block and rerun type and value inference.
  
      block_inputs = tuple(copy.copy(v) for v in self.loop_vars)
      for v in block_inputs:
          v._op = None
          v.op_output_idx = None
          v._child_ops = list()
          v.name = v.name + ".x"
          v._sym_val = v._sym_val
          v.consuming_blocks = list()
  
      block, exit_vars = self.build_block(block_inputs)
  
      # Verify exit_vars has the same types as loop_vars
      block_input_type_change = False
      for i, (v_in, v_out) in enumerate(zip(block_inputs, exit_vars)):
          if not is_subtype(v_out.sym_type, v_in.sym_type):
              compat_shape = while_loop.get_compat_shape(
                  v_out.sym_type, v_in.sym_type
              )
              if compat_shape is None:
                  msg = (
                      "loop_vars '{}' changes in the body of "
                      "while_loop '{}':\n {} -> {}"
                  )
                  raise ValueError(
                      msg.format(
                          v_in.name,
                          self.name,
                          v_in.sym_type,
                          v_out.sym_type,
                      )
                  )
              else:
                  block_inputs[i]._sym_type = types.tensor(
                      v_in.dtype, compat_shape
                  )
                  block_input_type_change = True
          if not while_loop._check_equal_value(
              v_out.sym_val, v_in.sym_val
          ):
              block_inputs[i]._sym_val = None
              block_input_type_change = True
  
      if block_input_type_change:
          # Since we are going to build the block again, we first need to remove ops
          # in the block from vars's _child_ops.
          while_loop.clean_up_child_ops(block)
  
          # Rebuild our block to invoke type inference.
          block, exit_vars = self.build_block(block_inputs)
          for i, (v_in, v_out) in enumerate(
              zip(block_inputs, exit_vars)
          ):
              if not is_subtype(v_out.sym_type, v_in.sym_type):
                  msg = (
                      "Block output {}: {} is not a subtype of "
                      + "block input {}: {} after factoring shape changes"
                  )
                  raise ValueError(
                      msg.format(
                          v_out.name.v.sym_type,
                          v_in.name,
                          v_in.sym_type,
                      )
                  )
              if not while_loop._check_equal_value(
                  v_out.sym_val, v_in.sym_val
              ):
                  msg = (
                      "Block output {}: {} is not equal to "
                      + "block input {}: {} after value changes"
                  )
                  raise ValueError(
                      msg.format(
                          v_out.name.v.sym_val, v_in.name, v_in.sym_val
                      )
                  )
      self.blocks.append(block)
  
imports: import six
  from coremltools.converters.mil.mil import types
  from coremltools.converters.mil.mil.types.type_mapping import numpy_val_to_builtin_val, is_subtype
  import copy
  from coremltools.converters.mil.mil import Block, SYMBOL, NONE
  from coremltools.converters.mil.mil.var import Var
  from coremltools.converters.mil.mil import get_new_symbol
  from ._op_reqs import *
  import logging
label_desc: Use image node_id 6 for calling the while_loop obj's underlying member method code with example usage: obj.build_nested_blocks() without return types