code: def compute_itershape(
      ctx: BaseContext,
      builder: ir.IRBuilder,
      in_shapes: tuple[ir.Instruction, ...],
      broadcast_pattern: tuple[tuple[bool, ...], ...],
  ):
      one = ir.IntType(64)(1)
      ndim = len(in_shapes[0])
      shape = [None] * ndim
      for i in range(ndim):
          for j, (bc, in_shape) in enumerate(
              zip(broadcast_pattern, in_shapes)
          ):
              length = in_shape[i]
              if bc[i]:
                  with builder.if_then(
                      builder.icmp_unsigned("!=", length, one),
                      likely=False,
                  ):
                      msg = f"Input {j} to elemwise is expected to have shape 1 in axis {i}"
                      ctx.call_conv.return_user_exc(
                          builder, ValueError, (msg,)
                      )
              elif shape[i] is not None:
                  with builder.if_then(
                      builder.icmp_unsigned("!=", length, shape[i]),
                      likely=False,
                  ):
                      with builder.if_else(
                          builder.icmp_unsigned("==", length, one)
                      ) as (
                          then,
                          otherwise,
                      ):
                          with then:
                              msg = (
                                  f"Incompatible shapes for input {j} and axis {i} of "
                                  f"elemwise. Input {j} has shape 1, but is not statically "
                                  "known to have shape 1, and thus not broadcastable."
                              )
                              ctx.call_conv.return_user_exc(
                                  builder, ValueError, (msg,)
                              )
                          with otherwise:
                              msg = (
                                  f"Input {j} to elemwise has an incompatible "
                                  f"shape in axis {i}."
                              )
                              ctx.call_conv.return_user_exc(
                                  builder, ValueError, (msg,)
                              )
              else:
                  shape[i] = length
      for i in range(ndim):
          if shape[i] is None:
              shape[i] = one
      return shape
  
file_path: pytensor/pytensor/link/numba/dispatch/elemwise_codegen.py
imports: from __future__ import annotations
  from typing import Any
  import numba
  import numpy
  from llvmlite import ir
  from numba import types
  from numba.core import cgutils
  from numba.core.base import BaseContext
  from numba.np import arrayobj
label_desc: Use image node_id 1 for calling a global function with example usage: compute_itershape(ctx, builder, in_shapes, broadcast_pattern) and returns: shape