class_docstr: Generalizes a core `Op` to work with batched dimensions.
  
  TODO: Dispatch JAX (should be easy with the vectorize macro)
  TODO: Dispatch Numba
  TODO: C implementation?
  TODO: Fuse Blockwise?
class_docstr_tok: ["Generalizes","a","core","`","Op","`","to","work","with","batched","dimensions",".","TODO",":","Dispatch","JAX","(","should","be","easy","with","the","vectorize","macro",")","TODO",":","Dispatch","Numba","TODO",":","C","implementation","?","TODO",":","Fuse","Blockwise","?"]
docstr: Parameters
  ----------
  core_op
      An instance of a subclass of `Op` which works on the core case.
  signature
      Generalized universal function signature,
      e.g., (m,n),(n)->(m) for vectorized matrix-vector multiplication
  gufunc: tuple, Optional
      Tuple containing:
          1. String import path for a numpy/scipy function (e.g., "numpy.matmul", "scipy.special.softmax")
          that implements the blockwised operation of the scalar op.
          2 Number of inputs of the function
          3 Number of outputs of the function
docstr_tok: ["Parameters","--","--","--","--","--","core_op","An","instance","of","a","subclass","of","`","Op","`","which","works","on","the","core","case",".","signature","Generalized","universal","function","signature",",","e.g.",",","(","m",",","n",")",",","(","n",")","-",">","(","m",")","for","vectorized","matrix-vector","multiplication","gufunc",":","tuple",",","Optional","Tuple","containing",":","1",".","String","import","path","for","a","numpy\/scipy","function","(","e.g.",",","``","numpy.matmul","''",",","``","scipy.special.softmax","''",")","that","implements","the","blockwised","operation","of","the","scalar","op",".","2","Number","of","inputs","of","the","function","3","Number","of","outputs","of","the","function"]
code: def __init__(
      self,
      core_op: Op,
      signature: Optional[str] = None,
      name: Optional[str] = None,
      gufunc_spec: Optional[tuple[str, int, int]] = None,
      **kwargs,
  ):
      """
  
      Parameters
      ----------
      core_op
          An instance of a subclass of `Op` which works on the core case.
      signature
          Generalized universal function signature,
          e.g., (m,n),(n)->(m) for vectorized matrix-vector multiplication
      gufunc: tuple, Optional
          Tuple containing:
              1. String import path for a numpy/scipy function (e.g., "numpy.matmul", "scipy.special.softmax")
              that implements the blockwised operation of the scalar op.
              2 Number of inputs of the function
              3 Number of outputs of the function
      """
      if isinstance(core_op, Blockwise):
          raise TypeError("Core Op is already a Blockwise")
  
      if signature is None:
          signature = getattr(core_op, "gufunc_signature", None)
          if signature is None:
              raise ValueError(
                  f"Signature not provided nor found in core_op {core_op}"
              )
  
      self.core_op = core_op
      self.signature = signature
      self.name = name
      self.inputs_sig, self.outputs_sig = _parse_gufunc_signature(
          signature
      )
      self.gufunc_spec = gufunc_spec
      self._gufunc = None
      super().__init__(**kwargs)
  
imports: from collections.abc import Sequence
  from copy import copy
  from typing import Any, Optional, cast
  import numpy
  from pytensor import config
  from pytensor.gradient import DisconnectedType
  from pytensor.graph.basic import Apply, Constant, Variable
  from pytensor.graph.null_type import NullType
  from pytensor.graph.op import Op
  from pytensor.graph.replace import _vectorize_node, _vectorize_not_needed, vectorize_graph
  from pytensor.scalar import ScalarType
  from pytensor.tensor import as_tensor_variable
  from pytensor.tensor.shape import shape_padleft
  from pytensor.tensor.type import TensorType, continuous_dtypes, discrete_dtypes, tensor
  from pytensor.tensor.utils import _parse_gufunc_signature, broadcast_static_dim_lengths, import_func_from_string
  from pytensor.tensor.variable import TensorVariable
label_desc: Use image node_id 1 to create a new Blockwise object from inherited base classes: Op with example: obj = Blockwise(core_op, signature, name, gufunc_spec)