code: def tile(cls, op):
      from ..datasource.zeros import TensorZeros
      from ..base import TensorTranspose
      from ..utils import reverse_order
      from .dot import TensorDot
      from .solve_triangular import TensorSolveTriangular
  
      tensor = op.outputs[0]
      in_tensor = op.input
      if has_unknown_shape(in_tensor):
          yield
      if in_tensor.nsplits[0] != in_tensor.nsplits[1]:
          # all chunks on diagonal should be square
          nsplits = in_tensor.nsplits[0]
          in_tensor = yield from recursive_tile(
              in_tensor.rechunk([nsplits, nsplits])
          )
  
      lower_chunks, upper_chunks = {}, {}
      for i in range(in_tensor.chunk_shape[0]):
          for j in range(in_tensor.chunk_shape[1]):
              if i < j:
                  lower_shape = (
                      in_tensor.nsplits[0][i],
                      in_tensor.nsplits[1][j],
                  )
                  lower_chunk = TensorZeros(
                      dtype=tensor.dtype,
                      shape=lower_shape,
                      order=tensor.order.value,
                  ).new_chunk(
                      None,
                      shape=lower_shape,
                      index=(i, j),
                      order=tensor.order,
                  )
                  upper_shape = (
                      in_tensor.nsplits[1][j],
                      in_tensor.nsplits[0][i],
                  )
                  upper_chunk = TensorZeros(
                      dtype=tensor.dtype,
                      shape=upper_shape,
                      order=tensor.order.value,
                  ).new_chunk(
                      None,
                      shape=upper_shape,
                      index=(j, i),
                      order=tensor.order,
                  )
                  lower_chunks[lower_chunk.index] = lower_chunk
                  upper_chunks[upper_chunk.index] = upper_chunk
              elif i == j:
                  target = in_tensor.cix[i, j]
                  if i > 0:
                      prev_chunks = []
                      for p in range(i):
                          a, b = lower_chunks[i, p], upper_chunks[p, j]
                          prev_chunk = TensorDot(
                              dtype=tensor.dtype
                          ).new_chunk(
                              [a, b],
                              shape=(a.shape[0], b.shape[1]),
                              order=tensor.order,
                          )
                          prev_chunks.append(prev_chunk)
  
                      cholesky_fuse_op = TensorCholeskyFuse()
                      lower_chunk = cholesky_fuse_op.new_chunk(
                          [target] + prev_chunks,
                          shape=target.shape,
                          index=(i, j),
                          order=tensor.order,
                      )
                  else:
                      lower_chunk = TensorCholesky(
                          lower=True, dtype=tensor.dtype
                      ).new_chunk(
                          [target],
                          shape=target.shape,
                          index=(i, j),
                          order=tensor.order,
                      )
  
                  upper_chunk = TensorTranspose(
                      dtype=lower_chunk.dtype
                  ).new_chunk(
                      [lower_chunk],
                      shape=lower_chunk.shape[::-1],
                      index=lower_chunk.index[::-1],
                      order=reverse_order(lower_chunk.order),
                  )
                  lower_chunks[lower_chunk.index] = lower_chunk
                  upper_chunks[upper_chunk.index] = upper_chunk
              else:
                  target = in_tensor.cix[j, i]
                  if j > 0:
                      prev_chunks = []
                      for p in range(j):
                          a, b = lower_chunks[j, p], upper_chunks[p, i]
                          prev_chunk = TensorDot(
                              dtype=tensor.dtype
                          ).new_chunk(
                              [a, b],
                              shape=(a.shape[0], b.shape[1]),
                              order=tensor.order,
                          )
                          prev_chunks.append(prev_chunk)
                      cholesky_fuse_op = TensorCholeskyFuse(
                          by_solve_triangular=True
                      )
                      upper_chunk = cholesky_fuse_op.new_chunk(
                          [target] + [lower_chunks[j, j]] + prev_chunks,
                          shape=target.shape,
                          index=(j, i),
                          order=tensor.order,
                      )
                  else:
                      upper_chunk = TensorSolveTriangular(
                          lower=True, dtype=tensor.dtype
                      ).new_chunk(
                          [lower_chunks[j, j], target],
                          shape=target.shape,
                          index=(j, i),
                          order=tensor.order,
                      )
                  lower_chunk = TensorTranspose(
                      dtype=upper_chunk.dtype
                  ).new_chunk(
                      [upper_chunk],
                      shape=upper_chunk.shape[::-1],
                      index=upper_chunk.index[::-1],
                      order=reverse_order(upper_chunk.order),
                  )
                  lower_chunks[lower_chunk.index] = lower_chunk
                  upper_chunks[upper_chunk.index] = upper_chunk
  
      new_op = op.copy()
      if op.lower:
          return new_op.new_tensors(
              op.inputs,
              tensor.shape,
              order=tensor.order,
              chunks=list(lower_chunks.values()),
              nsplits=in_tensor.nsplits,
          )
      else:
          return new_op.new_tensors(
              op.inputs,
              tensor.shape,
              order=tensor.order,
              chunks=list(upper_chunks.values()),
              nsplits=in_tensor.nsplits,
          )
  
imports: import numpy
  from numpy.linalg import LinAlgError
  from ...serialization.serializables import KeyField, BoolField
  from ...None import opcodes
  from ...core import recursive_tile
  from ...utils import has_unknown_shape
  from ..operands import TensorHasInput, TensorOperand, TensorOperandMixin
  from ..datasource import tensor
  from ..core import TensorOrder
  from ..array_utils import as_same_device, device
label_desc: Use image node_id 5 for calling the TensorCholesky obj's underlying member method code with example usage: obj.tile(cls, op) and returns: new_op, new_op