code: def estimate_size(cls, ctx, op):
      chunk = op.outputs[0]
      if op.stage == OperandStage.map:
          inp_chunk = chunk.inputs[0]
          inp_size, inp_calc = ctx[inp_chunk.key]
          store_overhead = np.int64().itemsize * inp_chunk.ndim
          calc_overhead = np.int64().itemsize * (inp_chunk.ndim + 2)
          ctx[chunk.key] = (
              store_overhead + inp_size,
              calc_overhead + inp_calc,
          )
      elif op.stage == OperandStage.reduce:
          sum_size = 0
          for shuffle_input in chunk.inputs[0].inputs or ():
              key = (shuffle_input.key, chunk.index)
              if ctx.get(key) is not None:
                  sum_size += ctx[key][0]
              else:
                  ctx[key] = None
          ctx[chunk.key] = (chunk.nbytes, max(sum_size, chunk.nbytes))
      else:
          super().estimate_size(ctx, op)
  
imports: import itertools
  import logging
  import numpy
  from ...None import opcodes
  from ...core import recursive_tile
  from ...core.operand import OperandStage
  from ...serialization.serializables import FieldTypes, KeyField, TupleField, StringField
  from ...utils import has_unknown_shape
  from ..array_utils import as_same_device, device
  from ..datasource import tensor
  from ..operands import TensorOperandMixin, TensorMapReduceOperand, TensorShuffleProxy
  from ..utils import get_order, decide_chunk_sizes
label_desc: Use image node_id 17 for calling the TensorReshape obj's underlying member method code with example usage: obj.estimate_size(cls, ctx, op) without return types