
# Autogenerated by mlir-tblgen; don't manually edit.

from ._ods_common import _cext as _ods_cext
from ._ods_common import (
    equally_sized_accessor as _ods_equally_sized_accessor,
    get_default_loc_context as _ods_get_default_loc_context,
    get_op_results_or_values as _get_op_results_or_values,
    segmented_accessor as _ods_segmented_accessor,
)
_ods_ir = _ods_cext.ir
_ods_cext.globals.register_traceback_file_exclusion(__file__)

import builtins
from typing import Any as _Any, Sequence as _Sequence, Union as _Union, Optional as _Optional
import sys as _sys
if _sys.version_info >= (3, 12):
  from collections.abc import Buffer as _Buffer  # pytype: disable=not-supported-yet
else:
  try:
    from typing_extensions import Buffer as _Buffer
  except ImportError:
    _Buffer = _Any


from ._transform_ops_gen import _Dialect

@_ods_cext.register_operation(_Dialect)
class ApplyGPUPromoteShuffleToAMDGPUPatternsOp(_ods_ir.OpView):
  r"""
  Collects patterns that are tryin to promote `gpu.shuffle`s to specialized
  AMDGPU intrinsics.
  """

  OPERATION_NAME = "transform.apply_patterns.gpu.gpu_shuffle_to_amdgpu"

  _ODS_REGIONS = (0, True)

  def __init__(self, *, chipset: _Optional[_Union[str, _ods_ir.StringAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    if chipset is not None: attributes["chipset"] = (chipset if (
        isinstance(chipset, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('StrAttr')) else
          _ods_ir.AttrBuilder.get('StrAttr')(chipset, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def chipset(self) -> _Optional[_ods_ir.StringAttr]:
    if "chipset" not in self.operation.attributes:
      return None
    return self.operation.attributes["chipset"]

  @chipset.setter
  def chipset(self, value: _Optional[_ods_ir.StringAttr]):
    if value is not None:
      self.operation.attributes["chipset"] = value
    elif "chipset" in self.operation.attributes:
      del self.operation.attributes["chipset"]

  @chipset.deleter
  def chipset(self):
    del self.operation.attributes["chipset"]

@_ods_cext.register_op_adaptor(ApplyGPUPromoteShuffleToAMDGPUPatternsOp)
class ApplyGPUPromoteShuffleToAMDGPUPatternsOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.apply_patterns.gpu.gpu_shuffle_to_amdgpu"

  @builtins.property
  def chipset(self) -> _Optional[_ods_ir.StringAttr]:
    if "chipset" not in self.attributes:
      return None
    return self.attributes["chipset"]

def apply_patterns_gpu_gpu_shuffle_to_amdgpu(*, chipset: _Optional[_Union[str, _ods_ir.StringAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ApplyGPUPromoteShuffleToAMDGPUPatternsOp:
  return ApplyGPUPromoteShuffleToAMDGPUPatternsOp(chipset=chipset, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ApplyGPURewritePatternsOp(_ods_ir.OpView):
  r"""
  Collects GPU rewrite patterns comprising:
    1. GpuAllReduceRewrite patterns
    2. GpuGlobalIdRewriter patterns
    3. GpuShuffleRewriter patterns
  """

  OPERATION_NAME = "transform.apply_patterns.gpu.gpu_rewrite_patterns"

  _ODS_REGIONS = (0, True)

  def __init__(self, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(ApplyGPURewritePatternsOp)
class ApplyGPURewritePatternsOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.apply_patterns.gpu.gpu_rewrite_patterns"

def apply_patterns_gpu_gpu_rewrite_patterns(*, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ApplyGPURewritePatternsOp:
  return ApplyGPURewritePatternsOp(loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ApplyGPUSubgroupReduceToNVVMConversionPatternsOp(_ods_ir.OpView):
  r"""
  Collects patterns that convert GPU dialect ops related to wmma ops
  to NVVM dialect ops.
  These patterns require an "LLVMTypeConverter".
  """

  OPERATION_NAME = "transform.apply_conversion_patterns.gpu.gpu_subgroup_reduce_to_nvvm"

  _ODS_REGIONS = (0, True)

  def __init__(self, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(ApplyGPUSubgroupReduceToNVVMConversionPatternsOp)
class ApplyGPUSubgroupReduceToNVVMConversionPatternsOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.apply_conversion_patterns.gpu.gpu_subgroup_reduce_to_nvvm"

def apply_conversion_patterns_gpu_gpu_subgroup_reduce_to_nvvm(*, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ApplyGPUSubgroupReduceToNVVMConversionPatternsOp:
  return ApplyGPUSubgroupReduceToNVVMConversionPatternsOp(loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ApplyGPUToNVVMConversionPatternsOp(_ods_ir.OpView):
  r"""
  Collects patterns that convert GPU dialect ops to NVVM dialect ops. These
  patterns require an "LLVMTypeConverter".
  """

  OPERATION_NAME = "transform.apply_conversion_patterns.gpu.gpu_to_nvvm"

  _ODS_REGIONS = (0, True)

  def __init__(self, *, benefit: _Optional[_Union[int, _ods_ir.IntegerAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    if benefit is not None: attributes["benefit"] = (benefit if (
        isinstance(benefit, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('I16Attr')) else
          _ods_ir.AttrBuilder.get('I16Attr')(benefit, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def benefit(self) -> _ods_ir.IntegerAttr:
    return self.operation.attributes["benefit"]

  @benefit.setter
  def benefit(self, value: _ods_ir.IntegerAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["benefit"] = value

@_ods_cext.register_op_adaptor(ApplyGPUToNVVMConversionPatternsOp)
class ApplyGPUToNVVMConversionPatternsOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.apply_conversion_patterns.gpu.gpu_to_nvvm"

  @builtins.property
  def benefit(self) -> _ods_ir.IntegerAttr:
    return self.attributes["benefit"]

def apply_conversion_patterns_gpu_gpu_to_nvvm(*, benefit: _Optional[_Union[int, _ods_ir.IntegerAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ApplyGPUToNVVMConversionPatternsOp:
  return ApplyGPUToNVVMConversionPatternsOp(benefit=benefit, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ApplyGPUToROCDLConversionPatternsOp(_ods_ir.OpView):
  r"""
  Collects patterns that convert GPU dialect ops to ROCDL dialect ops. These
  patterns require an "LLVMTypeConverter".
  """

  OPERATION_NAME = "transform.apply_conversion_patterns.gpu.gpu_to_rocdl"

  _ODS_REGIONS = (0, True)

  def __init__(self, chipset: _Union[str, _ods_ir.StringAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["chipset"] = (chipset if (
    isinstance(chipset, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(chipset, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def chipset(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["chipset"]

  @chipset.setter
  def chipset(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["chipset"] = value

@_ods_cext.register_op_adaptor(ApplyGPUToROCDLConversionPatternsOp)
class ApplyGPUToROCDLConversionPatternsOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.apply_conversion_patterns.gpu.gpu_to_rocdl"

  @builtins.property
  def chipset(self) -> _ods_ir.StringAttr:
    return self.attributes["chipset"]

def apply_conversion_patterns_gpu_gpu_to_rocdl(chipset: _Union[str, _ods_ir.StringAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ApplyGPUToROCDLConversionPatternsOp:
  return ApplyGPUToROCDLConversionPatternsOp(chipset=chipset, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ApplyGPUWwmaToNVVMConversionPatternsOp(_ods_ir.OpView):
  r"""
  Collects patterns that convert GPU dialect ops related to wmma ops
  to NVVM dialect ops.
  These patterns require an "LLVMTypeConverter".
  """

  OPERATION_NAME = "transform.apply_conversion_patterns.gpu.gpu_wmma_to_nvvm"

  _ODS_REGIONS = (0, True)

  def __init__(self, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(ApplyGPUWwmaToNVVMConversionPatternsOp)
class ApplyGPUWwmaToNVVMConversionPatternsOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.apply_conversion_patterns.gpu.gpu_wmma_to_nvvm"

def apply_conversion_patterns_gpu_gpu_wmma_to_nvvm(*, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ApplyGPUWwmaToNVVMConversionPatternsOp:
  return ApplyGPUWwmaToNVVMConversionPatternsOp(loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ApplyUnrollVectorsSubgroupMmaOp(_ods_ir.OpView):
  r"""
  Unrolls contractions to the target `m`, `n`, and `k` native vector size,
  along with other vector operations based on expected usage. `transfer_read`
  ops unroll based on the extract slice shape introduced by unrolling the
  contractions, while elementwise and `transfer_write` ops unroll to the shape of
  the C matrix (`m x n`).
  
  This operation applies to pure vector operations and should be applied before
  lowering to subgroup_mma ops.
  """

  OPERATION_NAME = "transform.apply_patterns.gpu.unroll_vectors_subgroup_mma"

  _ODS_REGIONS = (0, True)

  def __init__(self, m: _Union[int, _ods_ir.IntegerAttr], n: _Union[int, _ods_ir.IntegerAttr], k: _Union[int, _ods_ir.IntegerAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["m"] = (m if (
    isinstance(m, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('I64Attr')) else
      _ods_ir.AttrBuilder.get('I64Attr')(m, context=_ods_context))
    attributes["n"] = (n if (
    isinstance(n, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('I64Attr')) else
      _ods_ir.AttrBuilder.get('I64Attr')(n, context=_ods_context))
    attributes["k"] = (k if (
    isinstance(k, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('I64Attr')) else
      _ods_ir.AttrBuilder.get('I64Attr')(k, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def m(self) -> _ods_ir.IntegerAttr:
    return self.operation.attributes["m"]

  @m.setter
  def m(self, value: _ods_ir.IntegerAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["m"] = value

  @builtins.property
  def n(self) -> _ods_ir.IntegerAttr:
    return self.operation.attributes["n"]

  @n.setter
  def n(self, value: _ods_ir.IntegerAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["n"] = value

  @builtins.property
  def k(self) -> _ods_ir.IntegerAttr:
    return self.operation.attributes["k"]

  @k.setter
  def k(self, value: _ods_ir.IntegerAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["k"] = value

@_ods_cext.register_op_adaptor(ApplyUnrollVectorsSubgroupMmaOp)
class ApplyUnrollVectorsSubgroupMmaOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.apply_patterns.gpu.unroll_vectors_subgroup_mma"

  @builtins.property
  def m(self) -> _ods_ir.IntegerAttr:
    return self.attributes["m"]

  @builtins.property
  def n(self) -> _ods_ir.IntegerAttr:
    return self.attributes["n"]

  @builtins.property
  def k(self) -> _ods_ir.IntegerAttr:
    return self.attributes["k"]

def apply_patterns_gpu_unroll_vectors_subgroup_mma(m: _Union[int, _ods_ir.IntegerAttr], n: _Union[int, _ods_ir.IntegerAttr], k: _Union[int, _ods_ir.IntegerAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ApplyUnrollVectorsSubgroupMmaOp:
  return ApplyUnrollVectorsSubgroupMmaOp(m=m, n=n, k=k, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class EliminateBarriersOp(_ods_ir.OpView):
  r"""
  Removes unnecessary GPU barriers from the function. If a barrier does not
  enforce any conflicting pair of memory effects, including a pair that is
  enforced by another barrier, it is unnecessary and can be removed.
  
  The approach is based on "High-Performance GPU-to-CPU Transpilation and
  Optimization via High-Level Parallel Constructs" by  Moses, Ivanov,
  Domke, Endo, Doerfert, and Zinenko in PPoPP 2023. Specifically, it
  analyzes the memory effects of the operations before and after the given
  barrier and checks if the barrier enforces any of the memory
  effect-induced dependencies that aren't already enforced by another
  barrier.
  
  For example, in the following code
  
  ```mlir
    store %A
    barrier  // enforces load-after-store
    load %A
    barrier  // load-after-store already enforced by the previous barrier
    load %A
  ```
  
  the second barrier can be removed.
  """

  OPERATION_NAME = "transform.apply_patterns.gpu.eliminate_barriers"

  _ODS_REGIONS = (0, True)

  def __init__(self, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

@_ods_cext.register_op_adaptor(EliminateBarriersOp)
class EliminateBarriersOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.apply_patterns.gpu.eliminate_barriers"

def apply_patterns_gpu_eliminate_barriers(*, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> EliminateBarriersOp:
  return EliminateBarriersOp(loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class MapForallToBlocks(_ods_ir.OpView):
  r"""
  Target the gpu_launch op and rewrite the top level `scf.forall`
  to distributed gpu.block_id attribute. If `generate_gpu_launch` attribute
  is set, then first generates `gpu_launch` and moves the top level
  `scf.forall` inside.
  
  The operation searches top level `scf.forall` ops under
  `gpu_launch` and maps each such op to GPU blocks. Mapping is
  one-to-one and the induction variables of `scf.forall` are
  rewritten to gpu.block_id according to the `thread_dim_mapping` attribute.
  
  Dynamic, `scf.forall` trip counts are currently not supported.
  Dynamic block dim sizes are currently not supported.
  
  Only **bufferized** scf.forall are currently supported.
  Only scf.forall distributed to **at most 3 dimensions** are
  currently supported.
  
  The operation alters the block size of the given gpu_launch using the
  grid_dims argument.
  
  #### Return modes:
  
  This operation ignores non-gpu_launch ops and drops them in the return.
  
  If any scf.forall with tensors is found, the transform definitely
  fails.
  
  If all the `scf.forall` operations contained within the LaunchOp
  referred to by the `target` handle lower to GPU properly, the
  transform succeeds. Otherwise the transform definitely fails.
  
  The returned handle points to the same LaunchOp operand, consuming it and
  producing a new SSA value to satisfy chaining and linearity of the IR
  properties.
  """

  OPERATION_NAME = "transform.gpu.map_forall_to_blocks"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, target: _ods_ir.Value, *, grid_dims: _Optional[_Union[_Sequence[int], _ods_ir.DenseI64ArrayAttr]] = None, generate_gpu_launch: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(target)
    _ods_context = _ods_get_default_loc_context(loc)
    if grid_dims is not None: attributes["grid_dims"] = (grid_dims if (
        isinstance(grid_dims, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('DenseI64ArrayAttr')) else
          _ods_ir.AttrBuilder.get('DenseI64ArrayAttr')(grid_dims, context=_ods_context))
    if bool(generate_gpu_launch): attributes["generate_gpu_launch"] = _ods_ir.UnitAttr.get(
      _ods_get_default_loc_context(loc))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def target(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def grid_dims(self) -> _Optional[_ods_ir.DenseI64ArrayAttr]:
    if "grid_dims" not in self.operation.attributes:
      return None
    return self.operation.attributes["grid_dims"]

  @grid_dims.setter
  def grid_dims(self, value: _Optional[_ods_ir.DenseI64ArrayAttr]):
    if value is not None:
      self.operation.attributes["grid_dims"] = value
    elif "grid_dims" in self.operation.attributes:
      del self.operation.attributes["grid_dims"]

  @grid_dims.deleter
  def grid_dims(self):
    del self.operation.attributes["grid_dims"]

  @builtins.property
  def generate_gpu_launch(self) -> bool:
    return "generate_gpu_launch" in self.operation.attributes

  @generate_gpu_launch.setter
  def generate_gpu_launch(self, value):
    if bool(value):
      self.operation.attributes["generate_gpu_launch"] = _ods_ir.UnitAttr.get()
    elif "generate_gpu_launch" in self.operation.attributes:
      del self.operation.attributes["generate_gpu_launch"]

  @generate_gpu_launch.deleter
  def generate_gpu_launch(self):
    del self.operation.attributes["generate_gpu_launch"]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(MapForallToBlocks)
class MapForallToBlocksAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.gpu.map_forall_to_blocks"

  @builtins.property
  def target(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def grid_dims(self) -> _Optional[_ods_ir.DenseI64ArrayAttr]:
    if "grid_dims" not in self.attributes:
      return None
    return self.attributes["grid_dims"]

  @builtins.property
  def generate_gpu_launch(self) -> bool:
    return "generate_gpu_launch" in self.attributes

def gpu_map_forall_to_blocks(result: _ods_ir.Type, target: _ods_ir.Value, *, grid_dims: _Optional[_Union[_Sequence[int], _ods_ir.DenseI64ArrayAttr]] = None, generate_gpu_launch: _Optional[bool] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return MapForallToBlocks(result=result, target=target, grid_dims=grid_dims, generate_gpu_launch=generate_gpu_launch, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class MapNestedForallToThreads(_ods_ir.OpView):
  r"""
  Target the `gpu.launch op` and rewrite all `scf.forall` nested in it to
  distributed `gpu.thread_id` attribute.
  
  The operation searches for `scf.forall` ops nested under `target` and maps
  each such op to GPU threads.
  
  `scf.forall` induction variables are rewritten to `gpu.thread_id` according
  to the `mapping` attribute.
  
  Different types of mappings attributes are supported:
    - the block_dims is a list of integers that specifies the number of
      threads in each dimension. This is a mandatory attribute that is used
      to constrain the number of threads in each dimension. If an
      `scf.forall` op is mapped to fewer threads, predication occurs.
    - the warp_dims is a list of integers that specifies the number of
      warps in each dimension. This is an optional attribute that is used
      to constrain the number of warps in each dimension. When present, this
      attribute must be specified in a way that is compatible with the
      block_dims attribute. If an `scf.forall` op is mapped to fewer warps,
      predication occurs.
  
  Dynamic `scf.forall` trip counts are currently not supported.
  Dynamic block dim sizes are currently not supported.
  
  Only **bufferized** `scf.forall` are currently supported.
  Only `scf.forall` distributed to **at most 3 dimensions** are
  currently supported.
  
  The `sync_after_distribute`attribute controls whether a `gpu.barrier` is
  inserted after each scf.forall op. At this time, this is an all or nothing
  choice. This will need to be tightened in the future.
  
  The operation alters the block size of the given gpu_launch using the
  mandatory block_dims argument.
  
  #### Return modes:
  
  This operation ignores non-`gpu_launch` ops and drops them in the return.
  
  If any scf.forall with tensors is found, the transform definitely
  fails.
  
  If all the `scf.forall` operations with gpu.thread mapping contained
  within the `LaunchOp` referred to by the `target` handle lower to GPU
  properly, the transform succeeds. Otherwise the transform definitely
  fails.
  
  scf.forall operations with mappings other than gpu.thread are
  ignored.
  
  The returned handle points to the same LaunchOp operand, consuming it and
  producing a new SSA value to satisfy chaining and linearity of the IR
  properties.
  
  #### Example:
  
  ```
  gpu.launch blocks(%bx, %by, %bz) in (%x = %0, %y = %1, %z = %2)
             threads(%tx, %ty, %tz) in (%tx = %3, %ty = %4, %tz = %5) {
    scf.forall (%i, %j) in (7, 9) {
      ... // body 1
    } {mapping = [#gpu.thread<x>, #gpu.thread<y>, #gpu.thread<z>]}
    scf.forall (%i) in (12) {
      ... // body 2
    } {mapping = [#gpu.thread<x>]}
    gpu.terminator
  }
  ```
  
  is translated to:
  
  ```
  %bdimX = arith.constant 12 : index
  %bdimY = arith.constant 9 : index
  gpu.launch blocks(%bx, %by, %bz) in (%x = %0, %y = %1, %z = %2)
         threads(%tx, %ty, %tz) in (%tx = %bdimX, %ty = %bdimY, %tz = %5) {
    if (threadIdx.x < 9 && threadIdx.y < 7) {
      ... // body 1
    }
    gpu.barrier
    if (threadIdx.y < 1) {
      ... // body 2
    }
    gpu.barrier
    gpu.terminator
  }
  ```
  """

  OPERATION_NAME = "transform.gpu.map_nested_forall_to_threads"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, target: _ods_ir.Value, *, block_dims: _Optional[_Union[_Sequence[int], _ods_ir.DenseI64ArrayAttr]] = None, sync_after_distribute: _Optional[_Union[bool, _ods_ir.BoolAttr]] = None, warp_size: _Optional[_Union[int, _ods_ir.IntegerAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(target)
    _ods_context = _ods_get_default_loc_context(loc)
    if block_dims is not None: attributes["block_dims"] = (block_dims if (
        isinstance(block_dims, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('DenseI64ArrayAttr')) else
          _ods_ir.AttrBuilder.get('DenseI64ArrayAttr')(block_dims, context=_ods_context))
    if sync_after_distribute is not None: attributes["sync_after_distribute"] = (sync_after_distribute if (
        isinstance(sync_after_distribute, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('BoolAttr')) else
          _ods_ir.AttrBuilder.get('BoolAttr')(sync_after_distribute, context=_ods_context))
    if warp_size is not None: attributes["warp_size"] = (warp_size if (
        isinstance(warp_size, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('I64Attr')) else
          _ods_ir.AttrBuilder.get('I64Attr')(warp_size, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def target(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def block_dims(self) -> _ods_ir.DenseI64ArrayAttr:
    return self.operation.attributes["block_dims"]

  @block_dims.setter
  def block_dims(self, value: _ods_ir.DenseI64ArrayAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["block_dims"] = value

  @builtins.property
  def sync_after_distribute(self) -> _ods_ir.BoolAttr:
    return self.operation.attributes["sync_after_distribute"]

  @sync_after_distribute.setter
  def sync_after_distribute(self, value: _ods_ir.BoolAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["sync_after_distribute"] = value

  @builtins.property
  def warp_size(self) -> _ods_ir.IntegerAttr:
    return self.operation.attributes["warp_size"]

  @warp_size.setter
  def warp_size(self, value: _ods_ir.IntegerAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["warp_size"] = value

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(MapNestedForallToThreads)
class MapNestedForallToThreadsAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "transform.gpu.map_nested_forall_to_threads"

  @builtins.property
  def target(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def block_dims(self) -> _ods_ir.DenseI64ArrayAttr:
    return self.attributes["block_dims"]

  @builtins.property
  def sync_after_distribute(self) -> _ods_ir.BoolAttr:
    return self.attributes["sync_after_distribute"]

  @builtins.property
  def warp_size(self) -> _ods_ir.IntegerAttr:
    return self.attributes["warp_size"]

def gpu_map_nested_forall_to_threads(result: _ods_ir.Type, target: _ods_ir.Value, *, block_dims: _Optional[_Union[_Sequence[int], _ods_ir.DenseI64ArrayAttr]] = None, sync_after_distribute: _Optional[_Union[bool, _ods_ir.BoolAttr]] = None, warp_size: _Optional[_Union[int, _ods_ir.IntegerAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return MapNestedForallToThreads(result=result, target=target, block_dims=block_dims, sync_after_distribute=sync_after_distribute, warp_size=warp_size, loc=loc, ip=ip).result
